Resources

Troubleshooting

Symptom, cause, check, fix. The failures this SDK actually produces.

Every entry is a symptom you can see, the cause behind it, and the check that tells them apart. If none of these fit, get in touch with the request id.

Nothing renders after open()

The copilot draws nothing and no error appears anywhere.

  • The key is not a publishable key. init refuses anything that does not start with rd_pk_ (or nc_pk_, a key made before the rename), disables the copilot for the run and asserts in debug. Check Rendel.isInitialized.
  • The key is still the placeholder. rd_pk_test_... from an example is not a key. Copy your app's own from the console: Settings → API keys, Copy beside Test.
  • The copilot is switched off. RendelConfig(enabled: false) in code, or a kill switch published from the console, both make RendelLauncher draw nothing and open() return without presenting. Rendel.isEnabled tells you which state you are in.
  • init never ran, or ran after the widget built. It is a Future; await it in main before runApp.

Install fails

rendel is in private pilot and is not on pub.dev yet. It installs from a git reference; Install the SDK has the exact block. It needs Dart 3.5 and Flutter 3.24 or newer; older toolchains fail version solving rather than compilation.

The copilot answers but never calls my action

The model replies in prose about something your action was registered to do.

  • The manifest never synced. Registering an action queues a sync; if the device was offline at launch it fails, and open() retries it. Until a sync lands, every turn ends in manifest_unknown. Watch for manifest_sync_failed in your onLog sink.
  • The name was rejected. Action names are snake_case. The SDK asserts this at the line that declares the action; if you built the manifest by hand, the server rejects the whole document over one bad name.
  • The action is disabled. Check the Actions page in the console. A disabled action is not offered to the model at all, and the change takes effect on the next turn for every version of your app.
  • The description is doing no work. The model chooses from names, descriptions and parameter types. "Fetch the delivery status of an order by id" beats "order helper".

The confirmation card never appears, or stops working

  • The risk level is read. Only write and destructive produce a card. Read actions run immediately, by design.
  • It expired. A card is answerable for ten minutes, with a grace period for a handler that was already running. After that the model is told the user never answered.
  • Two actions in one turn. A confirmable action must be the only action call in a message. The server refuses the pair and asks the model to try again; you may see a turn take a beat longer.

Knowledge answers ignore my sources

  • Semantic retrieval is not switched on for your app yet. Until it is, the copilot answers from your actions and app state, and the console says so on the Knowledge page. Ask us to enable it.
  • The source is not ready. Sources are chunked on save and indexed when retrieval is enabled.
  • The console's test box is not the live path. It matches text; retrieval matches meaning. A passing test there does not prove a live answer will be grounded.

Theming does not apply

  • The palette was refused. fromTokens audits contrast and discards a whole published palette it cannot make legible, rather than applying half of it. The reason is reported through onLog.
  • The console published over you. A published appearance layers over your code config. Set RendelConfig(remoteConfig: false) to pin the build to exactly what your Dart says, and see whether the look changes.
  • You themed the sheet but not the launcher. Both read the same theme now; if the launcher looks wrong and the thread looks right, you are on an older SDK.

The stream drops, or the thread hangs

  • A turn that goes quiet is abandoned after RendelConfig.streamIdleTimeout, 45 seconds by default, and offers a retry.
  • A retry is safe. It resends the same turn_id, so the server recognises it and neither stores the message twice nor bills for it twice.
  • A retry that cannot help is not offered. At a cap or a rate limit the error is marked non-retryable and no Retry button is drawn.

Everything fails at once

  • Check the key's environment. A test key is sandbox: never billed, and it receives the draft console configuration. A live key receives the published one.
  • Check the app is not suspended. A suspended app answers every call with a quota error.
  • Check your API host. RendelConfig(apiBaseUrl:) must point at a host that resolves. The default is correct unless you overrode it.

Getting help

Send the request id. It is on turn.start, on the X-Request-Id response header, in every onLog record, and in our server logs. With it, a problem resolves to one turn: what was asked, what was rendered, which actions ran and what the server was doing. You can do that lookup yourself: paste it into the search on Conversations in the console. See Errors and Support.