Troubleshooting
Work out whether a problem is in your schema, query, transport, or Salesforce.
Start by isolating the layer
Call compile() before execute(). If compilation fails, the problem is local
to the query shape, generated schema, or values. If compilation succeeds but
execution fails, look at the executor, authentication, API version, permissions,
and Salesforce response.
When sharing a reproduction, include the smallest relevant query, generated schema fragment, sanitized error, and whether the query targets the API, static Apex, or dynamic Apex. Never include access tokens or production record data.
Installation and code generation
| Symptom | What to check |
|---|---|
| Unsupported Node version | Kysoql requires Node.js >=22.12.0 |
kysoql: command not found | Install @kysoql/codegen in the app and run its local binary through your package manager |
| Missing codegen authentication | Configure auth in kysoql.config.* or provide a trusted --auth module |
| Unknown object | Use the object API name and confirm that the generation identity can query it |
| Missing relationship paths | Include the related objects in codegen and regenerate |
| Invalid Describe response | Check the transport, API version, and raw Salesforce response before changing types |
Type errors
| Symptom | What it usually means |
|---|---|
| Field or path is rejected | It is missing from the generated schema or lacks the capability required by that method |
| Date or time string is rejected | Use soqlDate, soqlDateTime, or soqlTime in ordinary filters |
includes rejects a value | The field needs generated active multipicklist values |
| Selected property is missing | Select it explicitly. $if selections are optional and parent relationships can be null |
| Aggregate result has no useful key | Add .as(...) to row-producing aggregate selections |
groupBy or aggregate selection is unavailable | Start from an unselected root and group before selecting ordinary grouped fields |
HAVING or ordering rejects an alias | Use the grouped field or aggregate expression rather than the selected alias |
Methods disappear after .apex() | Finish normal query structure before switching to the narrower Apex compile context |
.execute() disappears after .apex() | Apex builders compile SOQL only. Execute that query from Apex |
Child .offset() is missing | Child offset is intentionally under the pilot namespace |
Compilation errors
| Problem | Fix |
|---|---|
| Empty selection | Select at least one field or expression |
Empty IN, NOT IN, or boolean group | Handle empty application inputs before building the predicate |
Invalid LIMIT or OFFSET | Use finite safe integers. Root offset is limited to 0..2000 |
Unbounded FIELDS(...) | Use an allowed bounded API query or choose explicit fields |
| Duplicate selection | Remove the overlapping field, selector, or alias |
| Semi-join rejected | Keep supported semi-joins at the root WHERE level and within the documented count |
Conflicting WITH clauses | Choose one filtering WITH form for the query |
| Object requires a filter | Check support boundaries |
FOR UPDATE conflicts | Remove ORDER BY or ALL ROWS |
clearGroupBy() fails | Rebuild the query without grouping-dependent selections or clauses |
| Child pilot offset fails | The immediate parent needs a literal LIMIT 1 |
| Knowledge Apex bind is rejected | Use a supported literal Knowledge query shape |
Execution problems
| Symptom | What to check |
|---|---|
No query executor configured | Pass an executor to Kysoql, or use the builder only for compile() |
| QueryAll or count is unsupported | The executor must implement the matching optional capability |
| Native response error | Inspect the sanitized Salesforce response metadata and paging locator |
| Query page or record budget exceeded | Narrow the query or deliberately raise the configured budget |
| Invalid JSforce result | Confirm that the adapter received a Salesforce query envelope with a record array |
| Incomplete response has no locator | Fix the transport or test double instead of accepting truncated data |
| Child records look incomplete | Native REST drains child locators. The JSforce adapter only drains root paging |
| Memory use is high | execute() collects root pages. Use explicit bounds or native REST async iteration |
executeAll() returns deleted records | QueryAll changes data visibility. Use ordinary execute() when that is not intended |
| Salesforce rejects typed SOQL | Check live metadata, permissions, API version, org features, and execution context |
Do not convert transport failures into an empty array. That makes an outage look like a valid query with no matching rows.
Field filtering errors
Field-rule names must be exact Salesforce API names. include and exclude
cannot be used together, include lists cannot be empty, and a rule cannot remove
every described field.
If a field unexpectedly disappears, check which identity ran codegen. Permission changes can make a previously visible field unavailable. See field filtering.
selectFields() is unavailable
Any explicit field rule makes that generated object partial, even when the rule
currently keeps every field. Kysoql disables selectFields(...) because
Salesforce expands FIELDS(...) from live org metadata rather than your local
subset.
Use explicit .select(...) calls, or remove the field rule and regenerate a
complete schema.