Common errors and how to fix them
Messages below are quoted from the packages. Values in<angle brackets> (and example slugs, keys, and hosts) vary with your project.
Definition errors (at import time)
defineIntegration() throws one error listing every problem, each prefixed with the path that failed:
ekanos validate reports the same problems as definition.schema or definition.load findings.
Slug is not kebab-case
[a-z0-9] segments separated by single hyphens:
Unrecognized key
effect/sensitivity into proposes.tools. If you are confident the key is valid, your project’s @ekanos/integration-schema may be newer than your CLI — run ekanos upgrade --check.
Widget id is invalid or duplicated
Tool name is not snake_case
Webhook, schedule, or action name is not kebab-case
actions) follow the same rule:
payment_intent.succeeded are never valid ids — map them to a kebab-case id and put the vendor’s name in description.
Cron expression is invalid
MON), macros (@daily), and a seconds field are not supported.
Fix:
OAuth endpoint is not covered by egress
oauth.provider.tokenUrl.
Fix: Add the origin of both endpoints:
Storage key is invalid
A key is"<dataType>" or "<dataType>/<subtype>". Two different messages can fire:
/ must be an allowed data type for its scope: activation, settings, metrics_summary, sync_state, or cache under storage.account; config, preferences, or cache under storage.user. secret is reserved — use ctx.secrets instead.
Fix:
Validation findings (ekanos validate)
ekanos validate exits 3 (validation) when there is at least one error-severity finding. Warnings alone do not fail it.
project.host-compiler-rules (warning)
checks/typecheck-host-rules pass compiles under strict and noUncheckedIndexedAccess. validate warns; ekanos publish escalates this finding to an error and refuses to submit.
Fix: Add to tsconfig.json:
project.slug-agreement (error)
collision.widget-id (error)
ekanos.json declare the same widget id. Tool names collide the same way (collision.tool-name), compared by their slug-prefixed effective names.
Fix: Prefix with your integration slug:
icons/pro-only (warning)
Use "fa-<alternative>" instead — the nearest Free equivalent.).
Runtime errors
Cannot find module @ekanos/sdk
Cause: Dependencies are not installed. Fix: Runpnpm install (or your package manager’s equivalent) after scaffolding.
StorageValidationError
ctx.storage throws StorageValidationError (code: 'STORAGE_VALIDATION_FAILED', with scope, key, and hint) when you access an undeclared key, write a value that fails the key’s schema, or read stored data that no longer matches the schema.
Fix for schema changes: Schema evolution is manual. Never loosen a schema in place — add a new key or widen with a union:
.optional() — a required field throws on every row written before the change.
EgressDeniedError
ctx.fetch for an origin not covered by egress (redirect targets included). The error has code: 'EGRESS_DENIED' and an origin property. On the host, an allowlisted name that resolves to a private, loopback, or link-local address is also refused, with a reason.
Fix: Add the origin to egress:
SecretAccessError
ctx.secrets.set() targeted a name that exists only in an admin-issued (source or global) tier. The error has code: 'SECRET_ACCESS_DENIED'.
Fix: Only write account-tier secrets — for example, OAuth tokens stored from onTokens. In tests, createMockContext({ secrets: { account: { … }, admin: { … } } }) reproduces the split.
NoRecordedResponseError (harness fixtures mode)
[harness:<slug>] refused GET https://api.acme.example/payments.
Cause: The harness is in fixtures mode and the request has no matching fixture for the active variant. It was refused, not sent.
Fix: Record the fixture in harness.config.ts:
live block to the entry and switch the toolbar to Live API.
No IntegrationActivationProvider is mounted
useActivateIntegration() / useDeactivateIntegration() reject with this message at call time when no provider is mounted.
Fix: The host and the dev harness both mount the provider. If you render an activation form in isolation (a test or Storybook), mount it yourself:
ctx.storage.user throws for machine actors
The SDK’s mock context throws:ctx.storage.user needs a user. A machine actor (ctx.actor.kind === 'machine') has none.
Fix: Use account-scoped storage for anything a machine actor — such as a workflow — can reach:
CLI errors (ekanos publish, ekanos status, …)
In JSON mode, errors arrive as { ok: false, error: { code, message, hint } }. The exit code and code always pair up.
Exit 4: auth_required
Run "ekanos login --host https://your-ekanos-host".
Other auth_required messages cover an expired or revoked session (for example, The stored session for https://your-ekanos-host is no longer valid.) and a pending MFA requirement.
Fix:
Exit 5: forbidden
You hold a seat on: my-source (developer). Run "ekanos use <slug>" with one of these.
Cause: ekanos use or ekanos publish targeted a source you hold no seat on.
Fix:
Exit 9: precondition_failed (schema skew)
@ekanos/integration-schema than the CLI bundles. validate and publish fail before loading your definition.
Fix:
npm i -D @ekanos/cli@latest, then re-run.
Exit 10: gate_failed
ekanos publish refuses before submitting when the local findings pass has errors:
ekanos status --watch exits 10 when the host gate rejects the submitted version:
data.findings, or with ekanos status --findings), fix them, bump the version, and publish again. Common gate failures:
- TypeScript errors under the host’s stricter rules (
checks/typecheck-host-rules) - Test failures (
checks/tests)
Still stuck?
- Read the hint — every CLI error carries an imperative
hint - Run with
--json—ekanos validate --jsongives the full findings list - Test locally —
ekanos testbefore publishing
- The exact error message
- Your
ekanos.jsonand the relevant section ofsrc/integration.ts - The output of
ekanos validate --json