{"record":{"id":"657f9838ad406724","repo":"deepseek-ai/deepseek-harness","slug":"notice-imagesunsupported","errorCode":null,"errorMessage":"notice.imagesUnsupported","messagePattern":"notice\\.imagesUnsupported","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/client/ui-commands/src/client/service.ts","lineNumber":332,"sourceCode":"   * popup, non-accepting claim, bare detached execute — throws the refusal\n   * so the machine surfaces one composer notice and the draft and images\n   * stay in place; nothing executes and nothing is dropped.\n   */\n  private async matchEnter(\n    session: ClientSessionContext,\n    line: string,\n    signal: AbortSignal,\n    envelope: SubmitEnvelope,\n  ): Promise<PickOutcome> {\n    const trimmed = line.trim()\n    if (!trimmed.startsWith('/')) return undefined\n    const ws = trimmed.search(/\\s/)\n    const token = ws === -1 ? trimmed : trimmed.slice(0, ws)\n    const bare = ws === -1\n    const name = token.slice(1)\n    if (name === '') return undefined\n    const refuseImages = (): never => {\n      throw new Error(this.t('notice.imagesUnsupported', { command: name }))\n    }\n    const contribution = this.live.contributions.get(name)\n    if (contribution !== undefined && contribution.available(session)) {\n      if (!bare) return undefined\n      if (envelope.images > 0) refuseImages()\n      this.openPopup(name, contribution.ui, session, { via: 'enter', token })\n      return 'handled'\n    }\n    await this.directory.ensureReady(session.sessionId, signal)\n    const desc = this.directory.resolve(session.sessionId, name)\n    if (desc === undefined) return undefined\n    // Bare enter on a decorated host command opens its popup; an argued line\n    // never consults the decoration (the claim/detached paths below own it).\n    if (bare) {\n      const decoration = this.live.decorations.get(name)\n      if (decoration !== undefined && decoration.available(session)) {\n        if (envelope.images > 0) refuseImages()\n        this.openPopup(name, decoration.ui, session, { via: 'enter', token })","sourceCodeStart":314,"sourceCodeEnd":350,"githubUrl":"https://github.com/deepseek-ai/deepseek-harness/blob/b150a551b8d465e31e418e1b2eaf5e79bbb7d28e/packages/client/ui-commands/src/client/service.ts#L314-L350","documentation":"matchEnter() adjudicates an Enter keypress on a slash-command token. When the command's live contribution is available in this session, the token is bare (no arguments after the command name), and the submission envelope carries image attachments, the localized notice key 'notice.imagesUnsupported' is thrown via refuseImages(): popup-style slash commands take no images, and the composer keeps the draft plus images for the user to fix.","triggerScenarios":"The user attaches or pastes images, then presses Enter on a bare recognized slash command (for example /model or /permission) whose contribution opens a popup — envelope.images > 0 with a bare token triggers refuseImages().","commonSituations":"Pasting a screenshot and then Enter-ing a settings slash command; drag-dropping an image while the composer already holds a bare command token; automated submit pipelines that always attach images regardless of draft content.","solutions":["Remove the image attachments from the composer (or send them with a plain-text prompt instead) and press Enter again","Add arguments after the command so the token is not bare, when the command accepts them","As a plugin author, give the command an images-capable handler instead of a popup UI if it should accept images"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const token = trimmed.split(/\\s/, 1)[0] ?? ''\nconst isBareSlash = token.startsWith('/') && token.length > 1 && trimmed === token\nif (isBareSlash && envelope.images > 0) {\n  // strip the images or warn before calling matchEnter\n}","typeGuard":null,"tryCatchPattern":"try {\n  handleEnter(service.matchEnter(session, envelope))\n} catch (error) {\n  if (error instanceof Error && error.message === t('notice.imagesUnsupported', { command: name })) {\n    showNotice(error.message) // draft and images are retained by design\n    return\n  }\n  throw error\n}","preventionTips":["Detach image attachments automatically when the draft becomes a bare slash token","Show an inline hint that the attached command accepts no images","Drive the Enter affordance's enabled state from image presence plus command availability"],"tags":["ui","slash-commands","image-attachments","localization"],"backgroundTag":"unsupported-attachment-type","analyzedSha":"b150a551b8d465e31e418e1b2eaf5e79bbb7d28e","analyzedAt":"2026-08-24T18:12:29.105Z","schemaVersion":2},"datasetVersion":"2026-08-24T22:17:12.610Z"}