Start with five quiet checks.
Most early issues are a typo, the wrong folder, or using a feature from the reference runtime with the small native alpha. Work from the smallest check to the largest—not from guesses.
- Confirm the command exists: reflex --version.
- Confirm you are in the folder containing the file: list the files and check the spelling.
- Validate without running: reflex check hello.rflx.
- Run the same file: reflex run hello.rflx.
- Read the filename, line, column, and message in the error before changing code.
If reflex --version works, Reflex is already installed. A later failure from reflex run hello.rflx is about the file or its code, not a request to reinstall the language.
CLI and file problems
| What you see | Likely cause | Fix |
|---|---|---|
reflex: command not found or equivalent | The installer was not completed, the terminal is old, or the command path is unavailable. | Close and reopen Terminal first. If it persists, use the platform installer again or ask the person who installed it to check the installation—not the program source. |
could not read hello.rflx | The file is not in the current folder or its name differs. | Change into the correct folder, use the exact path, and ensure the extension is really .rflx rather than .rflx.txt. |
| Extension warning | The file does not end in .rflx. | Rename it to the standard extension. The CLI may still read it, but editors and people will recognize it correctly. |
expected one .rflx file | Too many or too few command arguments. | Use exactly reflex run path/to/file.rflx, then check reflex --help if needed. |
Read an error before you edit.
A native CLI error is designed to start with a location. Treat it like a coordinate, not a verdict. In a message shaped like app.rflx:12:5: expected ':' before block, app.rflx is the file, 12 is the line, 5 is the column, and the final phrase is the immediate parser expectation.
- Open the named file and line.
- Read the line above it too; a missing closing quote, delimiter, or colon often changes what the next line means.
- Fix the first error only.
- Run
reflex checkagain. A later error may disappear once the parser can understand the earlier section.
If the message says an indent is inconsistent, inspect the leading spaces first. Replacing unrelated functions makes it harder to learn what caused the failure and can create new ones.
Syntax and indentation
reflex check is the fastest tool for syntax. It does not execute the program, so it is safe to use repeatedly while you edit.
# broken.rflx
if true:
print("This needs spaces")# fixed.rflx
if true:
print("This is inside the block")| Message pattern | Meaning | What to inspect |
|---|---|---|
tabs are not allowed for indentation | A tab begins a block line. | Configure the editor to insert spaces; re-indent the block consistently. |
inconsistent indentation | A line returns to a column that does not match an earlier block level. | Align sibling statements with the same number of spaces. |
expected ':' before block | An if, for, while, or block function is missing its colon. | Add : at the end of the opening line. |
a block begins on next line | Code appeared after a block colon instead of on an indented following line. | Press Enter after :, then indent. |
unclosed grouping delimiter | A ( or [ was not closed. | Pair the delimiters around the named line. |
The error location uses filename:line:column. Fix the first reported syntax error, then run check again—later messages may be consequences of the first one.
Runtime errors: ask what value you have.
When syntax is valid but run fails, isolate the expression on the reported line. Most runtime errors describe a mismatch between the operation and the value it received.
| Message pattern | Example cause | Repair |
|---|---|---|
is not callable | name() where name is a string. | Call functions only; remove parentheses from a value. |
has no property | Calling .upper() on a list. | Use a method documented for that receiver type, or convert/choose the right value. |
unknown builtin | Using an API not included in the native core. | Check the docs' release tags. Do not assume a similar language’s built-in exists. |
number needs a numeric string | number("twelve"). | Validate the input or keep it as text. |
range step cannot be zero | range(1, 10, 0). | Choose a positive or negative non-zero step. |
| Function expected at most … arguments | Calling a function with too many values. | Compare the call with its parameter list, including defaults. |
Add temporary print() statements just before the failing expression. Print the incoming value, a list’s .length, and the branch you expect to run. Remove the prints once the behavior is understood.
When it runs but gives the wrong answer.
A program can be syntactically valid and still be wrong. Start by writing one concrete input and the exact result you expect. Then make the program show its intermediate values at the boundary where the result becomes surprising.
# range ends before its final number
numbers = range(1, 5)
print(numbers.join(", ")) # 1, 2, 3, 4
# Include 5 by choosing an end of 6.
with_five = range(1, 6)
print(with_five.join(", "))| Symptom | Frequent cause | Focused check |
|---|---|---|
| One item is missing from a range | The end of range is excluded. | Print the entire generated list and verify the intended end value. |
| A branch is skipped | An empty list/string, 0, or null is false. | Print the condition and the value used by it immediately before if. |
| A transformed list is unchanged | The result of map, filter, or a string method was not assigned. | Store it in a named variable, then print old and new values. |
| An empty-list value surprises you | .first(), .last(), or .pop() yields null when no item exists. | Guard with if items.length > 0:. |
| A function sees an unexpected value | The caller passed fewer/more arguments or relied on a default incorrectly. | Print each parameter at function entry; compare call sites with the signature. |
Do not hide a behavior bug with a broad condition. State the invariant in code where possible: check an input is non-empty before taking its first item, or calculate a named is_valid value before using it in multiple branches.
Find where a value changed—or never existed.
For a failing function, print the arguments at entry, print the computed local value, and print just before return. This tells you whether the bug is in the caller, the function’s calculation, or the code that uses the returned result.
discount(price, percent = 0):
print(`price: ${price}`)
print(`percent: ${percent}`)
amount = price * percent / 100
print(`discount: ${amount}`)
return amount
print(discount(80, 25))Remember that an indented block has a local scope. If a value is intended to be used after an if or loop, initialize it outside the block and assign to it deliberately. If a name is only meaningful inside the branch that created it, use it there rather than making its lifetime unclear.
Check preconditions explicitly: confirm a list has an item before reading its first/last value, confirm text is numeric before passing it to number(), and select the correct list/string method for the receiver.
Reduce, check, observe, change one thing.
- Reduce: make a new tiny
repro.rflxcontaining only the failing behavior. - Check: run
reflex check repro.rflx. - Observe: use targeted
print()calls; write down expected output and actual output. - Change one thing: alter one expression, rerun, and keep notes. Avoid fixing five things at once.
- Lock in the repair: keep the small reproduction so it can become a regression test later.
# repro.rflx — keep it small
names = ["Ada"]
print(names.first())A short failing file is more valuable than a large description of a problem. It distinguishes a language bug from a project-specific mistake and makes future fixes testable.
Inspect data without guessing.
Use templates for readable debug output: print(`count: ${items.length}`). For a list, print its joined form and its length. For a branch, print a marker immediately inside each branch. For a function, print arguments at its entry and its return value just before returning.
items = ["one", "two"]
print(`items: ${items.join(" | ")}`)
print(`count: ${items.length}`)
if items.includes("two"):
print("found two")
else:
print("two is missing")Keep messages concrete. “entered save branch” is better than “here”; request id: … is better than printing a whole unrelated structure. Remove or gate temporary logging before sharing output that could contain private data.
Turn a repair into a small safety net.
After repairing a bug, keep the smallest example that would have caught it. You do not need a heavy framework to get value from this habit. A folder of small .rflx examples and expected terminal output creates a practical early regression suite.
- Save the minimized failing program with a descriptive name, such as
range-end-is-exclusive.rflx. - Add a comment with the expected output or behavior.
- Run
reflex checkandreflex runafter changes to the runtime or the program. - When a behavior is intentionally changed, update the example and explain why.
# expected output: 2, 4, 6
numbers = range(1, 7)
even = numbers.filter(fun(n) => n % 2 == 0)
print(even.join(", "))When you share a repair, include the version, command, input, and result. “Fixed the range bug” is not enough; “range(1, 7) now produces the expected end-exclusive sequence in Reflex 0.1.0-alpha.1” is checkable.
Separate a language defect from an install or platform issue.
Before changing source code, identify which layer failed:
| Layer | Quick proof | Next action |
|---|---|---|
| Installation | reflex --version prints a version. | If it does not, reopen the terminal and resolve installation/PATH ownership first. |
| File location | The exact file path is readable. | Use a correct folder or full path; do not edit a different copy by accident. |
| Syntax | reflex check file.rflx passes. | Fix the first location-specific parsing error. |
| Runtime logic | The program starts but output is wrong or a runtime error occurs. | Reduce and trace the value flow. |
| Unsupported feature | The program uses web, desktop, bridge, module, package, or another non-core API. | Read the release boundary; use the appropriate reference runtime only when deliberately developing there. |
The real downloadable artifact today is the tested Debian/Ubuntu Linux package. Windows and macOS packages are not marked as available until genuine outputs exist. A platform-specific installer problem should be reported with the package version and operating-system details, not misdiagnosed as a language syntax issue.
Web and desktop diagnosis
Web routes, CSS loading, desktop WebViews, and web()/native() belong to the Python reference runtime today. First verify which runtime you are using. An installed standalone CLI reporting an unknown builtin for web is an expected scope boundary, not a syntax bug.
- For a web route, print
request.methodandrequest.pathin middleware. - For CSS, confirm the path is next to the program as expected; prefer a tiny inline style while isolating a load issue.
- For generated desktop output, open the generated
index.htmlfirst. Then separately test the optionalpywebviewlauncher. - Do not expose a development server or desktop bridge to untrusted input without reviewing the security boundary.
Bridge worker failures
A bridge crosses a process boundary. Test both sides independently: run the foreign-language worker with a sample JSON request, then run the Reflex call. Confirm the external runtime exists (node, lua, dotnet, and so on), the target path is correct, and the worker prints one valid JSON response.
A bridge intentionally launches a program. Do not “fix” a bridge failure by accepting arbitrary commands or passing untrusted request text into a shell command. Use fixed, reviewed targets.
Write a report someone can act on.
If a minimal program still behaves incorrectly, include these items in the report:
- Reflex version from
reflex --versionand the operating system. - The smallest complete
.rflxfile that fails. - The exact command you ran.
- Actual output/error and what you expected instead.
- Whether
reflex checkpasses. - For reference-runtime features, the runtime/dependency versions and any worker program involved.
Remove passwords, tokens, personal paths, and private source before sending it. A report that is precise, small, and safe can become a regression test.
Know when the missing feature is the answer.
The 0.1 standalone runtime deliberately does not yet promise modules, package installation, network/web APIs, native desktop UI, language bridges, asynchronous I/O, source maps, debugger integration, or feature parity with the Python reference. Check the release scope before spending hours debugging an API that has not migrated yet.
Need the language reference?
Return to the full docs for syntax, functions, collection methods, application paths, and exact alpha boundaries.