stablyai/orca · error · Error
file does not contain a JSON object
Error message
file does not contain a JSON object
What it means
Thrown inside readPersistedState (then re-wrapped as error 539) when the persisted agent-hooks state file parses as valid JSON but the top-level value is not a plain object — e.g. it is an array, a number, a string, or null. isRecord() rejects arrays and null explicitly, so only a real key-value object passes. This inner Error is caught and converted to a RuntimeClientError with the path context.
Source
Thrown at src/cli/handlers/agent-hooks.ts:43
statuses: AgentHookInstallStatus[]
}
function getDataPath(): string {
return join(getDefaultUserDataPath(), 'orca-data.json')
}
function isRecord(value: unknown): value is Record<string, unknown> {
return typeof value === 'object' && value !== null && !Array.isArray(value)
}
function readPersistedState(dataPath: string): PersistedState {
if (!existsSync(dataPath)) {
return getDefaultPersistedState(homedir())
}
try {
const parsed = JSON.parse(readFileSync(dataPath, 'utf-8'))
if (!isRecord(parsed)) {
throw new Error('file does not contain a JSON object')
}
return parsed as PersistedState
} catch (error) {
throw new RuntimeClientError(
'runtime_error',
`Could not read ${dataPath}: ${error instanceof Error ? error.message : String(error)}`
)
}
}
function writePersistedState(dataPath: string, state: PersistedState): void {
mkdirSync(dirname(dataPath), { recursive: true })
const tmpPath = join(dirname(dataPath), `.${Date.now()}-${randomUUID()}.tmp`)
let renamed = false
try {
writeFileSync(tmpPath, `${JSON.stringify(state, null, 2)}\n`, 'utf-8')
renameSync(tmpPath, dataPath)
renamed = trueView on GitHub (pinned to 1136503c6a)
Solutions
- Restore the file to a JSON object shape (or delete it to regenerate defaults via getDefaultPersistedState).
- Back up the current file, then `rm <dataPath>` so the next run recreates a valid default state.
- Validate with `jq empty <file>` and ensure `jq -e 'type=="object"' <file>` succeeds.
Example fix
// before: ~/.config/orca/agent-hooks.json contains `[]` // after: replace with an object, or remove the file rm ~/.config/orca/agent-hooks.json
Defensive patterns
Strategy: type-guard
Validate before calling
import { readFileSync, existsSync } from 'node:fs'
function readStateObject(dataPath: string): Record<string, unknown> {
if (!existsSync(dataPath)) return {}
const parsed = JSON.parse(readFileSync(dataPath, 'utf-8'))
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
throw new Error(`${dataPath} root is not a JSON object`)
}
return parsed as Record<string, unknown>
} Type guard
function isRecord(value: unknown): value is Record<string, unknown> {
return typeof value === 'object' && value !== null && !Array.isArray(value)
} Prevention
- Validate persisted files against the expected schema before trusting them.
- Keep backups before hand-editing state files.
When it happens
Trigger: The dataPath file contains JSON.parse-able content whose root is an array, primitive, or null. Examples: '[]', '42', '"hello"', 'null'. Note malformed JSON throws a SyntaxError instead (still caught at 539).
Common situations: User hand-edited the agent-hooks state file and saved an array, an external tool wrote a non-object schema, or a prior version wrote a different top-level shape.
Related errors
- runtime_error
- Artifact share records could not be read safely.
- Failed to persist Codex session index-heal outcome for ${thr
- [plain-node-entry-guard] could not smoke-load daemon-entry.j
- Missing packaged resources directory: ${resourcesDir}
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/65e2237216ac8255.
Report an issue: GitHub.