Troubleshooting
11.1 Lint Exit States
Read last line. Know action.
| Exit | State | Files Changed? | Action |
|---|---|---|---|
| 0 | CLEAN | No | Continue. Skip commit. |
| 0 | FIXED | Yes | onde git commit. Done. |
| 1 | ERROR | No | Fix listed lines. Re-run onde lint. |
| 3 | WARNINGS | No | Commit safe. Fix later. |
Rule: Exit 1 = atomic. Zero writes. Fix all errors first.
11.2 Error & Warning Matrix
Find message. Apply fix. Re-run.
| Message | Cause | Fix |
|---|---|---|
unknown type "X" | Type not in schema | Add to schema or change type:: |
invalid value "X" for status | Enum mismatch | Use valid value or extend schema enum |
required property "X" missing | Schema demands it | Add property or set @default in schema |
broken link [[X]] | Target missing or deleted | Create node or remove link |
partial link [[X]] — N matches | Title ambiguous | Use ID [[task-882]] or full title |
wrong edge target | Type mismatch | Link to correct node type |
expected "key:: value" | Malformed line | Fix spacing. Exact :: required. |
column mismatch | Dense row ≠ header cols | Match pipe count exactly |
unclosed edge properties | Missing } | Close brace |
file/dir over budget | Token limit exceeded | Trim body, split file, or raise budget |
block over row limit | Dense block exceeds @max-rows | Split file or enable @auto-split |
file over node limit | File exceeds @max-nodes | Split file or enable @auto-split |
dir over node limit | Dir total exceeds @max-dir-nodes | Archive, merge, or raise limit |
dir violation | File in wrong folder | Run onde organize --dirs or move manually |
naming violation | Filename breaks @naming | Run onde organize --rename |
rejected extension | Wrong file type in dir | Move/delete file or remove @reject-ext |
@ext conflicts with @naming | Extension mismatch | Align @ext with @naming template |
duplicate id "X" | Two nodes share ID | Change one ID or remove id:: (auto-gen replaces) |
Rule: Errors block writes. Warnings do not. Fix errors → exit 0.
11.3 CLI Cheat Sheet
Pick by workflow. Flags stack.
Sync & Heal
| Command | Purpose |
|---|---|
onde lint | Full sync + validate + auto-fix |
onde lint --dry-run | Preview changes. Zero writes. |
onde lint --soft | Errors → warnings. Exit 0. |
onde lint --watch | Auto-sync on file save. |
onde lint --continue-on-error | Write valid files. Skip broken ones. |
Query & Traverse
| Command | Purpose |
|---|---|
onde find <type> [flags] | Filter, sort, group, output |
onde q '<dsl>' | Pipes, multi-hop, negation, variables |
onde deps <id> | Follow depends edges only |
onde ancestors <id> | Follow ALL edges upstream |
onde impact <id> | Full downstream fan-out |
onde find --as-of T | Query graph at past moment |
Organize & Recover
| Command | Purpose |
|---|---|
onde organize | Format, sort, group, normalize |
onde organize --split | One file → many |
onde organize --split --batch-size N | Batch paginate: N per file |
onde organize --merge | Many files → one |
onde organize --dirs | Move files to match schema |
onde relink --to id | Stabilize all links |
onde materialize | Rebuild markdown from truth |
Git & Output
| Command | Purpose |
|---|---|
onde git commit | Auto-message. Stage changed files only. |
--format md | Full nodes. Round-trip safe. |
--format md-dense | Compact rows. Agent-friendly. |
--format json | Scripts, APIs, LLM input. |
--format table | Terminal scan. |
--format mermaid | Diagrams. |
11.4 Query DSL Grammar
Wrap complex queries in single quotes. Start simple. Graduate when needed.
| Element | Syntax | Example |
|---|---|---|
| Node filter | type[key=value] | task[status=BLOCKED] |
| Date filter | today, -7d, +3d, YYYY-MM-DD | deadline < today |
| Forward edge | >edge> | task >depends> task |
| Backward edge | <edge< | person <owns< task |
| Wildcard | >*{max:N} | issue >*{max:5} |
| Pipe | | | | group by status | count |
| Aggregation | count, avg X, sum X | | count, avg priority |
| Having | having agg op N | | having count > 3 |
| Sort | sort field asc/desc | | sort deadline asc |
| Negation | NOT >edge> node | task NOT >depends> task |
| Variable | $var = expr | $p = person <owns< task |
| Set ops | UNION, INTERSECT, EXCEPT | (A) INTERSECT (B) |
Rule: Pipes chain left→right. Variables bind once. Negation subtracts matches.
11.5 Schema Directive Reference
Directives stack. Schema controls validation. Remove schema = opt-out.
| Directive | Effect | Example |
|---|---|---|
@required | Fails lint if missing | status: enum(...) @required |
@default(X) | Auto-fills when empty | priority: enum(...) @default(C) |
@auto(now) | Sets timestamp on creation | created_at: datetime @auto(now) |
@on-update | Overwrites timestamp every lint | updated_at: datetime @on-update |
@check("A > B") | Compares two fields | @check("deadline > created_at") |
@pattern("regex") | Validates string format | code: string @pattern("^[A-Z]{3}-\\d{3}$") |
@max-length(N) | Caps string length | title: string @max-length(200) |
@unique | Value must be distinct per type | slug: string @unique |
@deprecated("msg") | Warns on use. Still works. | old: string @deprecated("use slug") |
@many(min:N, max:M) | Edge cardinality bounds | assignees: edge(person) @many(min:1, max:5) |
@soft | Downgrades errors to warnings | tasks/**: type(task) @soft |
@naming("{id}.md") | Enforces filename pattern | tasks/**: type(task) @naming("{id}.md") |
@max-file-tokens(N) | Per-file token limit | tasks/**: @max-file-tokens(500) |
@max-dir-tokens(N) | Per-directory token limit | memory/**: @max-dir-tokens(10000) |
@max-rows(N) | Max pipe rows per dense block | tasks/**: @max-rows(50) |
@max-nodes(N) | Max nodes per file | decisions/**: @max-nodes(10) |
@max-dir-nodes(N) | Max nodes per directory | tasks/**: @max-dir-nodes(500) |
@auto-split | Auto batch-split on violation | tasks/**: @max-rows(30) @auto-split |
@ext(ext1 ext2) | Set file extensions to parse | tasks/**: @ext(task.md) |
@reject-ext(ext1) | Block specific extensions in dir | tasks/**: @reject-ext(txt csv json) |
Rule: Directives live on fields or directory rules. Schemaful = enforced. Schemaless = ignored.
11.6 Terminal Fallback
Binary unavailable? Bulk edit needed? Use raw tools. onde lint heals after.
| Goal | Command |
|---|---|
| Find nodes by type | rg 'type:: task' tasks/ -l |
| Find broken links | rg '\[\[task-999\]\]' tasks/ -l |
| Replace property | sed -i 's/^status:: BLOCKED$/status:: TODO/' tasks/*.md |
| Add missing field | sed -i '/^deadline::/a points:: 0' tasks/*.md |
| Extract all IDs | rg '^id:: ' . --type md -o | sort -u |
| Count by type | rg '^type:: ' . --type md -o | sort | uniq -c | sort -rn |
Rule: Backup first. Test on one file. Run onde lint after bulk changes.
11.7 Recovery Checklist
Disaster → step-by-step fix.
| Scenario | Fix Path |
|---|---|
| Output looks wrong | onde lint → onde organize |
| Links broken after move | onde relink --to id → onde lint |
| Schema too strict | onde lint --soft or mv .onde/schema.md .onde/schema.md.bak |
| Accidentally deleted files | onde materialize |
| Git merge conflicts in markdown | git pull → onde lint (auto-heals) |
| Lint blocks on one bad file | onde lint --continue-on-error |
| Context window full | onde tree --over-budget → trim or split fat files |
| Query returns stale data | onde lint → re-run query |
| Edits vanish in query result | Add --fields to query line |
| Workspace feels chaotic | onde schema extract > .onde/schema.md → review → onde lint --soft |
Rule: Truth lives in journal. Markdown disposable. Sync heals chaos. One command fixes most drift.
Next Step: → Appendices: Migration, Performance, Glossary, Templates