{"record":{"id":"b7275c339f218c87","repo":"deepseek-ai/deepseek-harness","slug":"the-host-offers-no-permission-command","errorCode":null,"errorMessage":"the host offers no /permission command","messagePattern":"the host offers no /permission command","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/client/ui-permission-presets/src/client/index.ts","lineNumber":154,"sourceCode":"  ctx.effect(() => command.decorate({\n    name: 'permission',\n    // The picker exists exactly while the projection does: a permission-less\n    // host serves no key and the bare invocation falls through to the host\n    // command (which is absent too — the line simply misses).\n    available: session => selectOf(sessionFor(session)) !== undefined,\n    ui: {\n      kind: 'popupSelect',\n      options: (session) => {\n        const value = selectOf(sessionFor(session))\n        if (value === undefined) throw new Error('permission presets are not available on this host')\n        return Promise.resolve(optionsOf(value, t))\n      },\n      onSelect: async (option, session) => {\n        const live = sessionFor(session)\n        if (live === undefined) throw new Error('this session is not materialized yet')\n        const result = await live.command(`/permission ${option.id}`)\n        if (!result.ok) throw new Error(`permission switch failed: ${result.error.code}: ${result.error.message}`)\n        if (!result.value.matched) throw new Error('the host offers no /permission command')\n      },\n    },\n  }), 'ui-permission: /permission decoration')\n}\n","sourceCodeStart":136,"sourceCodeEnd":159,"githubUrl":"https://github.com/deepseek-ai/deepseek-harness/blob/b150a551b8d465e31e418e1b2eaf5e79bbb7d28e/packages/client/ui-permission-presets/src/client/index.ts#L136-L159","documentation":"After live.command('/permission <id>') succeeds at the RPC layer, result.value.matched === false means the line was delivered but the host has no registered /permission command: the client-side presets decoration assumes a capability the host build does not provide. This is the deliberate loud failure for that capability mismatch.","triggerScenarios":"A web client with ui-permission-presets talking to an older or smaller host build whose command registry lacks /permission; a custom host profile assembled without the permission command plugin; a partially upgraded deployment.","commonSituations":"Version skew between the client bundle and the host; trimmed host profiles; staging environments running mismatched halves.","solutions":["Upgrade the host to a build that registers the /permission command","Or remove/hide the presets decoration in compositions targeting hosts without it","Feature-detect before rendering the control: probe the command directory for 'permission'"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const known = directory.resolve(sessionId, 'permission')\nif (known === undefined) hidePermissionDecoration(sessionId)","typeGuard":null,"tryCatchPattern":"try {\n  await applyPreset(option.id)\n} catch (error) {\n  if (error instanceof Error && error.message === 'the host offers no /permission command') {\n    hidePermissionDecoration(sessionId) // capability gap, not a transient failure\n    return\n  }\n  throw error\n}","preventionTips":["Gate host-dependent decorations on a live catalog probe","Ship web client and host from the same release train","Feature-detect once per session scope, not per render"],"tags":["version-skew","permissions","slash-commands","host"],"backgroundTag":"command-not-found","analyzedSha":"b150a551b8d465e31e418e1b2eaf5e79bbb7d28e","analyzedAt":"2026-08-24T18:12:29.105Z","schemaVersion":2},"datasetVersion":"2026-08-24T22:17:12.610Z"}