Skip to content

fix: pass explicit basename to send_document to prevent silent delivery failure - #68107

Closed
rkfshakti wants to merge 1 commit into
NousResearch:mainfrom
rkfshakti:fix/telegram-send-document-basename
Closed

rkfshakti wants to merge 1 commit into
NousResearch:mainfrom
rkfshakti:fix/telegram-send-document-basename

Conversation

@rkfshakti

Copy link
Copy Markdown
Contributor
  • fix(write_file): detect cwd-shaped relative paths missing leading slash
  • fix(write_file): coerce cwd-shaped relative paths in _resolve_path_for_task
  • fix(write_file): structural cwd-shape detection instead of allowlist
  • fix(telegram): pass explicit basename to send_document to prevent silent delivery failure

@alt-glitch alt-glitch added type/bug Something isn't working tool/file File tools (read, write, patch, search) platform/telegram Telegram bot adapter P2 Medium — degraded but workaround exists sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages duplicate This issue or pull request already exists labels Jul 20, 2026
@alt-glitch

Copy link
Copy Markdown
Contributor

This was generated by AI during triage.

Duplicate of #67426 for the identical cwd-shaped path correction. This PR additionally bundles a Telegram document-basename change, which should be split for independent review.

@rkfshakti rkfshakti changed the title fix/telegram send document basename fix: pass explicit basename to send_document to prevent silent delivery failure Jul 20, 2026

@Bryntly Bryntly 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.

Reviewing test coverage:

  1. tools/file_tools.py changes are well-covered by the new tests in tests/tools/test_file_tools_cwd_resolution.py, including both the fast-path allowlist and structural detection fallback.
  2. The changes in tools/send_message_tool.py add filename=os.path.basename(media_path) to bot.send_document calls for Telegram. However, there are no new tests or updates to existing Telegram tests (e.g., tests/tools/test_send_message_tool.py or tests/tools/test_telegram_send_message_caption.py) to verify this new filename parameter is passed correctly. Please add a test case to ensure the filename is extracted and passed to the Telegram bot as expected.

@Bryntly Bryntly 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.

The changes look solid. The structural path detection approach in _coerce_missing_leading_slash safely prevents the path-doubling bug, and the explicit os.path.basename in the telegram integration correctly resolves the silent document delivery failure. Code quality and tests are up to standard.

@Bryntly Bryntly 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.

Reviewing the error handling and silent failures in the modified telegram code (_send_telegram in tools/send_message_tool.py), I found a few issues:

  1. Missing warning append for caption-fallback failures:
    Around line 1300, if the caption-fallback send fails (except Exception as _cap_err:), the error is only logged via logger.warning but NOT appended to the warnings list. This means the failure is silent from the agent's perspective because the error won't be returned in the tool output. You should add warnings.append(_sanitize_error_text(_cap_err)).

  2. Silent downgrade of audio/voice files on caption parse error:
    In the caption parse retry block (elif media_kwargs.get("parse_mode"), around lines 1397-1408), the checks for elif ext in _VOICE_EXTS and is_voice: and elif ext in _TELEGRAM_SEND_AUDIO_EXTS: are missing (unlike the primary try block and the thread-not-found retry block). If an audio or voice file encounters a caption parse error, it will fall through to else: last_msg = await bot.send_document(...) and be silently sent as a generic document instead of a voice/audio message.

  3. Inconsistent filename propagation:
    The PR explicitly passes filename=os.path.basename(media_path) to bot.send_document to fix silent delivery failures. If the underlying issue in python-telegram-bot affects file objects without explicit names, consider whether bot.send_audio, bot.send_video, etc., also need the filename argument to be safe, especially in the retry blocks.

@Bryntly Bryntly 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.

I have reviewed the code for security issues and unsafe patterns.

The function introduces a dangerous unsafe pattern. Specifically:

    # Fast path: first segment is a well-known filesystem root.
    first_segment = filepath.split('/', 1)[0]
    if first_segment in _ABSOLUTE_PATH_ROOTS:
        return '/' + filepath

If a user or model passes a legitimate relative path intended for the workspace (e.g., or ), this function unconditionally prepends a , turning it into an absolute path (, ).

  1. Path Traversal / Containment Break: This forces the path resolution out of the intended workspace directory and accesses the host's root filesystem.
  2. Broken Functionality: It breaks normal relative path access for any project that happens to have a folder named , , integer 10 readonly !=0
    integer 10 readonly '#'=0
    integer 10 readonly '$'=7847
    array readonly '*'=( )
    readonly -=569X
    0=zsh
    integer 10 readonly '?'=127
    array readonly @=( )
    ANTIGRAVITY_AGENT=1
    ANTIGRAVITY_CONVERSATION_ID=eb9be3c7-347d-4508-8a66-7d06ed04fcb3
    ANTIGRAVITY_CSRF_TOKEN=''
    ANTIGRAVITY_LS_ADDRESS=localhost:61582
    ANTIGRAVITY_PROJECT_ID=default-cli-project
    ANTIGRAVITY_SAFECLIS_SOURCE=/Users/pacman/.gemini/antigravity-cli/bin/safeclis/src
    ANTIGRAVITY_SOURCE_METADATA='{"tool":{"conversationId":"eb9be3c7-347d-4508-8a66-7d06ed04fcb3", "stepIndex":6, "toolCall":{"id":"wb2j7w01", "name":"run_command", "argumentsJson":"{"CommandLine":"gh pr review 68107 --comment -b \"I have reviewed the code for security issues and unsafe patterns.\n\nThe _coerce_missing_leading_slash function introduces a dangerous unsafe pattern. Specifically:\n\n\\\\\\\\python\\n # Fast path: first segment is a well-known filesystem root.\\n first_segment = filepath.split('\''/'\'', 1)[0]\\n if first_segment in _ABSOLUTE_PATH_ROOTS:\\n return '\''/'\'' + filepath\\n\\\\\\\\\\\n\nIf a user or model passes a legitimate relative path intended for the workspace (e.g., data/config.json or tmp/test.py), this function unconditionally prepends a /, turning it into an absolute path (/data/config.json, /tmp/test.py). \n\n1. Path Traversal / Containment Break: This forces the path resolution out of the intended workspace directory and accesses the host'''s root filesystem. \n2. Broken Functionality: It breaks normal relative path access for any project that happens to have a folder named data, tmp, private, etc, etc. at its root. \n\nThis fast path based on a hardcoded list of common root directories is highly unsafe and should be removed. The structural detection (checking if the joined path nests the base dir) is much safer, though care must be taken that paths cannot escape the sandbox.\"","Cwd":"/Users/pacman/GITHUB_ACTUAL/.worktrees-pr-babysit/HERMES-pr-68107","WaitMsBeforeAsync":5000,"toolAction":"Reviewing PR","toolSummary":"Review PR 68107"}", "thinkingSignature":"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", "originalName":"run_command"}}}'
    ANTIGRAVITY_TRAJECTORY_ID=e5a12ed3-0e11-46a8-9f33-eddd4ec3e1c9
    integer 10 readonly ARGC=0
    BAT_THEME='Monokai Extended'
    BUN_INSTALL=/Users/pacman/.bun
    CC_LANGFUSE_SECRET_KEY=sk-lf-local-claude-code
    tied cdpath CDPATH=''
    CLOUDSDK_CONFIG=/Users/pacman/.config/gcloud
    CLOUDSDK_PYTHON=/Users/pacman/.pkgx/python.org/v3.14.6/bin/python3.14
    CODEX_HOME=/Users/pacman/.codex
    integer 10 COLUMNS=166
    CPUTYPE=arm64
    EDITOR='/opt/homebrew/bin/code --wait'
    integer 10 EGID=20
    ELEVENLABS_API_KEY=sk_db5f475f8d3e611cb7f5d7300e06538519d2318647e142de
    EMBEDDING_API_KEY=lmstudio-local
    EMBED_ALLOW_CLOUD=0
    EMBED_HARRIER_ONLY=1
    EMBED_PROVIDER_POLICY=quality_first
    integer 10 EUID=501
    EZA_ICONS_AUTO=always
    tied fignore FIGNORE=''
    tied fpath FPATH=/opt/homebrew/share/zsh/site-functions:/Users/pacman/.grok/completions/zsh:/Users/pacman/.local/share/zsh/site-functions:/Users/pacman/.docker/completions:/Users/pacman/.oh-my-zsh/custom/plugins/zsh-syntax-highlighting:/Users/pacman/.oh-my-zsh/custom/plugins/zsh-autosuggestions:/Users/pacman/.oh-my-zsh/plugins/git:/Users/pacman/.oh-my-zsh/completions:/Users/pacman/.oh-my-zsh/cache/completions:/usr/share/zsh/site-functions:/usr/share/zsh/5.9/functions
    integer 10 FUNCNEST=700
    FZF_DEFAULT_OPTS=' --height=42% --layout=reverse --border=rounded --inline-info --prompt='''💖 ''' --pointer='''▶''' --marker='''◆''' --color=bg:#191919,bg+:#272822,fg:#f8f8f2,fg+:#f8f8f2,hl:#f92672,hl+:#ff2d95,info:#a6e22e,marker:#fd971f,pointer:#66d9ef,prompt:#ff2d95,spinner:#ae81ff,header:#66d9ef,border:#ff2d95'
    GEMINI_CLI_SYSTEM_SETTINGS_PATH=/Users/pacman/.gemini/system-settings.json
    GH_CONFIG_DIR=/Users/pacman/.config/gh-ssh
    GH_TOKEN=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
    integer 10 GID=20
    GITHUB_MCP_PAT=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
    GITHUB_PERSONAL_ACCESS_TOKEN=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
    GITHUB_TOKEN=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
    GOOGLE_APPLICATION_CREDENTIALS=/Users/pacman/.gcloud-key.json
    GOOGLE_CLOUD_PROJECT=eastern-royal-callcenter
    GOOGLE_CLOUD_PROJECT_ID=eastern-royal-callcenter
    GPG_TTY=/dev/ttys002
    HF_HOME=/Users/pacman/.cache/huggingface
    HISTCHARS='!^#'
    integer 10 readonly HISTCMD=0
    integer 10 HISTSIZE=30
    HOME=/Users/pacman
    HOMEBREW_CELLAR=/opt/homebrew/Cellar
    HOMEBREW_PREFIX=/opt/homebrew
    HOMEBREW_REPOSITORY=/opt/homebrew
    HOST=num5.local
    IFS=$' \t\n\C-@'
    INFOPATH=/opt/homebrew/share/info:
    KEYBOARD_HACK=''
    integer KEYTIMEOUT=40
    LANG=C.UTF-8
    LESS=-R
    integer 10 readonly LINENO=1
    integer 10 LINES=49
    integer LISTMAX=100
    LMSTUDIO_API_BASE=http://127.0.0.1:1234/v1
    LMSTUDIO_EMBED_CANDIDATES=text-embedding-harrier-oss-v1-27b,microsoft/text-embedding-harrier-oss-v1-27b,harrier-emb
    LMSTUDIO_EMBED_MODEL=text-embedding-harrier-oss-v1-27b
    LM_STUDIO_TOKEN_MODE=auto
    LOGNAME=pacman
    LSCOLORS=Gxfxcxdxbxegedabagacad
    LS_COLORS='di=1;36:ln=35:so=32:pi=33:ex=31:bd=34;46:cd=34;43:su=30;41:sg=30;46:tw=30;42:ow=30;43'
    MACHTYPE=x86_64
    integer MAILCHECK=60
    tied mailpath MAILPATH=''
    tied manpath MANPATH=''
    MODEL_RUNNER_URL=http://localhost:12434
    tied module_path MODULE_PATH=/usr/lib/zsh/5.9
    NO_PROXY=oauth2.googleapis.com,oauth2.googleapis.com
    NULLCMD=cat
    OLDPWD=/Users/pacman/GITHUB_ACTUAL/.worktrees-pr-babysit/HERMES-pr-68107
    OLLAMA_API_KEY=905c67a4fb8f49b3bcc24e2ab9fc3e5a.jG8iD1rbrLtJA-mihrp4Vpej
    OLLAMA_BLOCKED_MODELS=gpt-oss:120b,gpt-oss:20b,gpt-oss:latest
    OLLAMA_CLOUD_API_BASE=https://ollama.com/api
    OLLAMA_CLOUD_EMBED_MODEL=''
    OLLAMA_EMBED_CANDIDATES=''
    OLLAMA_EMBED_MODEL=''
    OLLAMA_HOST=http://127.0.0.1:11434
    OLLAMA_MODELS=/Users/pacman/.ollama
    OLLAMA_ROUTER_POLICY=quality_first
    OPTARG=''
    OPTIMIZER_API_KEY=lmstudio-local
    integer 10 OPTIND=1
    OSTYPE=darwin25.0
    OTEL_SERVICE_NAME=gemini-antigravity
    P9K_SSH=1
    P9K_TTY=old
    PAGER=less
    tied path PATH=/Users/pacman/bin:/Users/pacman/.codex/mcp_tools/BIN:/Users/pacman/.codex/local/bin:/Users/pacman/.codex/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/Users/pacman/.gemini/antigravity-cli/bin:/Users/pacman/.bun/bin:/Users/pacman/.grok/bin:/Users/pacman/google-cloud-sdk/bin:/Users/pacman/GITHUB_ACTUAL/ANSIBLE_CONFIG/bin:/Users/pacman/.antigravity-ide/antigravity-ide/bin:/Users/pacman/.antigravity/antigravity/bin:/opt/homebrew/opt/mysql-client/bin:/Users/pacman/.swiftly/bin:/Applications/Tailscale.app/Contents/MacOS:/Users/pacman/.local/bin:/Users/pacman/.langflow/uv:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/pkg/env/global/bin:/Library/Apple/usr/bin:/Applications/Wireshark.app/Contents/MacOS:/usr/local/go/bin:/Users/pacman/.cargo/bin:/Users/pacman/.lmstudio/bin:/Users/pacman/.lmstudio/bin
    integer 10 readonly PPID=64922
    PROMPT=''
    PROMPT2=''
    PROMPT3='?# '
    PROMPT4='+%N:%i> '
    PS1=''
    PS2=''
    PS3='?# '
    PS4='+%N:%i> '
    tied psvar PSVAR=''
    PWD=/Users/pacman/GITHUB_ACTUAL/.worktrees-pr-babysit/HERMES-pr-68107
    integer 10 RANDOM=9003
    READNULLCMD=more
    ROOSTER_GMAIL_APP_PASSWORD='aoap mrmf mqew msxa'
    integer 10 SAVEHIST=0
    integer 10 SECONDS=0
    SENTRY_AUTH_TOKEN=0a2bb27f6f3e24bd17b6dd239998f325e639a830dc778041c632a35feb9324be
    SENTRY_LOAD_DOTENV=0
    SHELL=/bin/zsh
    integer 10 SHLVL=4
    SPROMPT='zsh: correct '''%R''' to '''%r''' [nyae]? '
    SSH_CLIENT='100.106.40.80 61458 22'
    SSH_CONNECTION='100.106.40.80 61458 100.106.40.80 22'
    SSH_TTY=/dev/ttys002
    SWIFTLY_BIN_DIR=/Users/pacman/.swiftly/bin
    SWIFTLY_HOME_DIR=/Users/pacman/.swiftly
    SWIFTLY_TOOLCHAINS_DIR=/Users/pacman/Library/Developer/Toolchains
    TERM=xterm-256color
    TIMEFMT='%J %U user %S system %P cpu %E total'
    TMPDIR=/var/folders/x9/q0xhkyp94_3c942b0h_2gdlh0000gn/T/
    TMPPREFIX=/tmp/zsh
    TRANSFORMERS_CACHE=/Users/pacman/.cache/huggingface/hub
    integer 10 TRY_BLOCK_ERROR=-1
    integer 10 TRY_BLOCK_INTERRUPT=-1
    TTY=/dev/tty
    integer 10 readonly TTYIDLE=274484
    integer 10 UID=501
    USER=pacman
    USERNAME=pacman
    VENDOR=apple
    VISUAL='/opt/homebrew/bin/code --wait'
    undefined WATCH
    WORDCHARS='
    ?_-.[]~=/&;!#$%^(){}<>'
    ZSH=/Users/pacman/.oh-my-zsh
    ZSH_ARGZERO=zsh
    readonly tied zsh_eval_context ZSH_EVAL_CONTEXT=cmdarg:cmdsubst
    ZSH_EXECUTION_STRING=$'gh pr review 68107 --comment -b "I have reviewed the code for security issues and unsafe patterns.\n\nThe _coerce_missing_leading_slash function introduces a dangerous unsafe pattern. Specifically:\n\n\\\\python\n # Fast path: first segment is a well-known filesystem root.\n first_segment = filepath.split(\'/\', 1)[0]\n if first_segment in _ABSOLUTE_PATH_ROOTS:\n return \'/\' + filepath\n\\\\\\n\nIf a user or model passes a legitimate relative path intended for the workspace (e.g., data/config.json or tmp/test.py), this function unconditionally prepends a /, turning it into an absolute path (/data/config.json, /tmp/test.py). \n\n1. Path Traversal / Containment Break: This forces the path resolution out of the intended workspace directory and accesses the host's root filesystem. \n2. Broken Functionality: It breaks normal relative path access for any project that happens to have a folder named data, tmp, private, etc, etc. at its root. \n\nThis fast path based on a hardcoded list of common root directories is highly unsafe and should be removed. The structural detection (checking if the joined path nests the base dir) is much safer, though care must be taken that paths cannot escape the sandbox."'
    ZSH_NAME=zsh
    ZSH_PATCHLEVEL=zsh-5.9-0-g73d3173
    integer 10 readonly ZSH_SUBSHELL=1
    ZSH_VERSION=5.9
    _=private
    _P9K_TTY=/dev/ttys002
    undefined aliases
    array argv=( )
    undefined builtins
    array tied CDPATH cdpath=( )
    undefined commands
    undefined dirstack
    undefined dis_aliases
    undefined dis_builtins
    undefined dis_functions
    undefined dis_functions_source
    undefined dis_galiases
    undefined dis_patchars
    undefined dis_reswords
    undefined dis_saliases
    array tied FIGNORE fignore=( )
    array unique tied FPATH fpath=( /opt/homebrew/share/zsh/site-functions /Users/pacman/.grok/completions/zsh /Users/pacman/.local/share/zsh/site-functions /Users/pacman/.docker/completions /Users/pacman/.oh-my-zsh/custom/plugins/zsh-syntax-highlighting /Users/pacman/.oh-my-zsh/custom/plugins/zsh-autosuggestions /Users/pacman/.oh-my-zsh/plugins/git /Users/pacman/.oh-my-zsh/completions /Users/pacman/.oh-my-zsh/cache/completions /usr/share/zsh/site-functions /usr/share/zsh/5.9/functions )
    undefined funcfiletrace
    undefined funcsourcetrace
    undefined funcstack
    undefined functions
    undefined functions_source
    undefined functrace
    undefined galiases
    histchars='!^#'
    undefined history
    undefined historywords
    undefined jobdirs
    undefined jobstates
    undefined jobtexts
    undefined keymaps
    array tied MAILPATH mailpath=( )
    array tied MANPATH manpath=( )
    array tied MODULE_PATH module_path=( /usr/lib/zsh/5.9 )
    undefined modules
    mount_authenticator_shm=/pam745B6C134CD9
    undefined nameddirs
    no_proxy=oauth2.googleapis.com,oauth2.googleapis.com
    undefined options
    undefined parameters
    undefined patchars
    array tied PATH path=( /Users/pacman/bin /Users/pacman/.codex/mcp_tools/BIN /Users/pacman/.codex/local/bin /Users/pacman/.codex/bin /opt/homebrew/bin /opt/homebrew/sbin /Users/pacman/.gemini/antigravity-cli/bin /Users/pacman/.bun/bin /Users/pacman/.grok/bin /Users/pacman/google-cloud-sdk/bin /Users/pacman/GITHUB_ACTUAL/ANSIBLE_CONFIG/bin /Users/pacman/.antigravity-ide/antigravity-ide/bin /Users/pacman/.antigravity/antigravity/bin /opt/homebrew/opt/mysql-client/bin /Users/pacman/.swiftly/bin /Applications/Tailscale.app/Contents/MacOS /Users/pacman/.local/bin /Users/pacman/.langflow/uv /usr/local/bin /System/Cryptexes/App/usr/bin /usr/bin /bin /usr/sbin /sbin /var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin /var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin /var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin /pkg/env/global/bin /Library/Apple/usr/bin /Applications/Wireshark.app/Contents/MacOS /usr/local/go/bin /Users/pacman/.cargo/bin /Users/pacman/.lmstudio/bin /Users/pacman/.lmstudio/bin )
    array pipestatus=( 0 )
    prompt=''
    array tied PSVAR psvar=( )
    undefined reswords
    undefined saliases
    service=DOCKERHUB_API_KEY
    array signals=( EXIT HUP INT QUIT ILL TRAP ABRT EMT FPE KILL BUS SEGV SYS PIPE ALRM TERM URG STOP TSTP CONT CHLD TTIN TTOU IO XCPU XFSZ VTALRM PROF WINCH INFO USR1 USR2 ZERR DEBUG )
    integer 10 readonly status=127
    undefined termcap
    undefined terminfo
    undefined userdirs
    undefined usergroups
    undefined watch
    undefined widgets
    array readonly tied ZSH_EVAL_CONTEXT zsh_eval_context=( cmdarg cmdsubst )
    undefined zsh_scheduled_events, , etc. at its root.

This fast path based on a hardcoded list of common root directories is highly unsafe and should be removed. The structural detection (checking if the joined path nests the base dir) is much safer, though care must be taken that paths cannot escape the sandbox.

@Bryntly Bryntly 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.

I have reviewed the code for security issues and unsafe patterns.

The _coerce_missing_leading_slash function introduces a dangerous unsafe pattern. Specifically:

    # Fast path: first segment is a well-known filesystem root.
    first_segment = filepath.split("/", 1)[0]
    if first_segment in _ABSOLUTE_PATH_ROOTS:
        return "/" + filepath

If a user or model passes a legitimate relative path intended for the workspace (e.g., data/config.json or tmp/test.py), this function unconditionally prepends a /, turning it into an absolute path (/data/config.json, /tmp/test.py).

  1. Path Traversal / Containment Break: This forces the path resolution out of the intended workspace directory and accesses the host's root filesystem.
  2. Broken Functionality: It breaks normal relative path access for any project that happens to have a folder named data, tmp, private, etc, etc. at its root.

This fast path based on a hardcoded list of common root directories is highly unsafe and should be removed. The structural detection (checking if the joined path nests the base dir) is much safer, though care must be taken that paths cannot escape the sandbox.

@rkfshakti

Copy link
Copy Markdown
Contributor Author

Thanks for the triage note. You're right that the cwd-shaped path correction overlaps with #67426 — I should have checked for existing coverage before filing.

Regarding the Telegram document-basename change: that's a separate fix for #67552 (pass explicit basename to send_document to prevent silent delivery failure). I'll split it into its own PR so each change can be reviewed independently. This PR will then focus only on the cwd-shaped relative path fix (or be closed as a duplicate of #67426 if the maintainers prefer).

…dling in Telegram media send

Three fixes in the Telegram _send_telegram function:

1. **Explicit filename for send_document:** Added filename=os.path.basename(media_path) to all three send_document call sites (primary send, thread-not-found retry, and caption-parse retry). Without an explicit filename, python-telegram-bot derives the filename from the file object, which can be a temp path or truncated — causing silent delivery failure on some platforms.

2. **Caption-fallback warning propagation:** The caption-fallback failure handler (when the file is gone and the caption text is sent alone) logged the error via logger.warning but never appended it to the warnings list, making the failure invisible to the agent. Now warnings.append() is called alongside the log.

3. **Voice/audio handling in caption parse retry:** The caption parse retry block was missing the voice and audio type checks that exist in the primary try block and the thread-not-found retry block. If an audio or voice file encountered a caption parse error, it would fall through to send_document instead of send_voice/send_audio, potentially failing or misrepresenting the media type.

Fixes NousResearch#67552
@rkfshakti
rkfshakti force-pushed the fix/telegram-send-document-basename branch from dcfd4db to 31fab4c Compare July 22, 2026 07:55
@rkfshakti

Copy link
Copy Markdown
Contributor Author

Closing this PR as planned — the cwd-shaped path correction is a duplicate of #67426, and the Telegram send_document basename fix has been split into a clean PR with all review feedback addressed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

duplicate This issue or pull request already exists P2 Medium — degraded but workaround exists platform/telegram Telegram bot adapter sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages tool/file File tools (read, write, patch, search) type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants