Skip to content

fix(cli): TypeError concatenating queued note onto image (multimodal) message#37081

Closed
xxxigm wants to merge 3 commits into
NousResearch:mainfrom
xxxigm:fix/cli-image-model-note-typeerror
Closed

fix(cli): TypeError concatenating queued note onto image (multimodal) message#37081
xxxigm wants to merge 3 commits into
NousResearch:mainfrom
xxxigm:fix/cli-image-model-note-typeerror

Conversation

@xxxigm

@xxxigm xxxigm commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes a crash in the interactive CLI agent thread:

TypeError: can only concatenate str (not "list") to str

Related Issue:
No issue filed. Reported on Discord by privacydied ( https://discord.com/channels/1053877538025386074/1511137568224444426/1511137568224444426 ).

Repro:

  1. Start hermes
  2. /model gpt-5.5 --provider openai-codex (queues a pending model-switch note)
  3. Paste an image and send it in the same turn

Root cause: attaching an image to a vision-capable model turns the user message into a list of OpenAI-style content parts (text + image_url). The queued /model (and /reload-skills) note was prepended with note + "\n\n" + agent_message, which is str + listTypeError. The adjacent _voice_prefix block already guarded with isinstance(message, str), but these two note-prepend blocks did not.

Fix: add _prepend_note_to_message() that:

  • strf"{note}\n\n{message}" (unchanged behavior)
  • list → folds the note into the first {"type": "text"} part, or inserts a leading text part for image-only messages
  • unknown shapes → returned unchanged (fail-open)

Used for both the model-switch and skills-reload notes. Original message is not mutated.

Test plan

  • scripts/run_tests.sh tests/cli/test_prepend_note_to_message.py — covers str/list folding, image-only insertion, empty-note passthrough, unknown-shape fail-open, and the exact multimodal repro shape.

xxxigm added 3 commits June 2, 2026 07:02
Sending an image to a vision model turns the user message into a list of
OpenAI-style content parts. When a /model or /reload-skills note was queued
for the same turn, the CLI did `note + "\n\n" + agent_message`, crashing the
agent thread with:

    TypeError: can only concatenate str (not "list") to str

Repro: `/model gpt-5.5 --provider openai-codex`, then paste+send an image.

Add _prepend_note_to_message(), which folds the note into the first text
part of a content-parts list (or inserts a leading text part for image-only
messages) and keeps the plain-string path unchanged. Used for both the
model-switch and skills-reload notes.
Regression coverage for the multimodal-message TypeError: note folding into
text parts, image-only insertion, empty-note passthrough, and unknown-shape
fail-open.
Adopt the cleaner handling from PR NousResearch#37080: coerce/strip the note and
skip the extra newlines when the underlying message (or text part) is
empty, while keeping the safer fail-open behavior for unknown shapes.

@tonydwb tonydwb left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Summary

Verdict: Approved

Review Notes

  • PR #37081fix(cli): TypeError concatenating queued note onto image (multimodal) message by @xxxigm

✅ Looks Good

  • Correct fix: The root cause is clearly identified — str + list TypeError when a queued note (/model or /reload-skills) is concatenated with a multimodal content-parts list.
  • Clean helper function: _prepend_note_to_message() handles str, list (with/without text part), and unknown shapes via fail-open. Well-documented.
  • No mutation of original: Immutability is preserved throughout.
  • Good test coverage: 6 tests covering all branches — str, empty note, list-with-text, image-only, exact repro shape, unknown shape.
  • Well-scoped fix: Only 2 source files touched (cli.py + new test file), 100 additions total.

💡 Suggestions (Non-Blocking)

  • Consider extracting this to a shared utility if other parts of the codebase ever need similar note-prepend behavior.

Reviewed by Hermes Agent

@teknium1

teknium1 commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Merged via #37173 (#37173). Your three commits were rebased onto current main with your authorship preserved in git log (043350d, a26a12a, c35ede7). Thanks for the clean fix and the thorough edge-case tests. cc @helix4u who hit the same root cause in #37080 and closed his own in favor of this one's coverage — both credited.

@teknium1 teknium1 closed this Jun 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants