{"record":{"id":"737822a7b867c059","repo":"crewAIInc/crewAI","slug":"append-failed-exit-code-exit-code-output-geta","errorCode":null,"errorMessage":"append failed: exit_code={exit_code}, output={getattr(response, 'result', '')!r}","messagePattern":"append failed: exit_code=(.+?), output=(.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"lib/crewai-tools/src/crewai_tools/tools/daytona_sandbox_tool/daytona_file_tool.py","lineNumber":373,"sourceCode":"\n        quoted_temp = shlex.quote(temp_path)\n        quoted_target = shlex.quote(path)\n        response = sandbox.process.exec(\n            f\"cat {quoted_temp} >> {quoted_target}; \"\n            f\"rc=$?; rm -f {quoted_temp}; exit $rc\"\n        )\n\n        exit_code = getattr(response, \"exit_code\", 0)\n        if exit_code != 0:\n            try:\n                sandbox.fs.delete_file(temp_path)\n            except Exception:\n                logger.debug(\n                    \"Best-effort temp-file cleanup failed after append \"\n                    \"error; the file may need manual deletion.\",\n                    exc_info=True,\n                )\n            raise RuntimeError(\n                f\"append failed: exit_code={exit_code}, \"\n                f\"output={getattr(response, 'result', '')!r}\"\n            )\n\n        try:\n            info = sandbox.fs.get_file_info(path)\n            total_bytes = getattr(info, \"size\", None)\n        except Exception:\n            total_bytes = None\n\n        return {\n            \"status\": \"appended\",\n            \"path\": path,\n            \"appended_bytes\": len(chunk),\n            \"total_bytes\": total_bytes,\n        }\n\n    @staticmethod","sourceCodeStart":355,"sourceCodeEnd":391,"githubUrl":"https://github.com/crewAIInc/crewAI/blob/754d7323beb2fd042e33444a115ea2d5a47193f0/lib/crewai-tools/src/crewai_tools/tools/daytona_sandbox_tool/daytona_file_tool.py#L355-L391","documentation":"DaytonaFileTool._append implements append by writing a temp file and running a shell append command via sandbox.process.code_run; if that process returns a non-zero exit_code it raises RuntimeError with the code and captured output. Before raising it best-effort deletes the temp file (failures only logged at debug). Common underlying causes are a missing parent directory, permission denial, or a read-only filesystem inside the sandbox.","triggerScenarios":"_run(action='append', path='/newdir/file.txt', content='x') where /newdir does not exist; appending to a file owned by another user; disk full in the sandbox; the sandbox process API returning a non-zero code for the internal cat/append command.","commonSituations":"Agents appending logs to a path whose directory was never created (mkdir step skipped); sandboxes with restricted write permissions; transient sandbox process failures surfacing as opaque exit codes.","solutions":["Inspect the output= field in the RuntimeError message — it contains the sandbox-side stderr explaining the failure.","Ensure the parent directory exists first: _run(action='mkdir', path=parent) or create the file with action='write' before appending.","Check permissions/free space in the sandbox (action='info' on the path).","Retry once if the output suggests a transient sandbox error; report the full message if it persists."],"exampleFix":"# before (parent dir may not exist)\nfile_tool._run(action='append', path='/logs/run.log', content='line\\n')\n\n# after\nfile_tool._run(action='mkdir', path='/logs')\nfile_tool._run(action='append', path='/logs/run.log', content='line\\n')","handlingStrategy":"try-catch","validationCode":"def append_safe(file_tool, path: str, content: str, *, binary: bool = False):\n    parent = path.rsplit('/', 1)[0] or '/'\n    if not file_tool._run(action='exists', path=parent).get('exists'):\n        file_tool._run(action='mkdir', path=parent)\n    return file_tool._run(action='append', path=path, content=content, binary=binary)","typeGuard":null,"tryCatchPattern":"try:\n    result = file_tool._run(action='append', path=p, content=c)\nexcept RuntimeError as e:\n    msg = str(e)\n    if 'exit_code=' in msg:\n        # msg carries sandbox-side output; create parent dir and retry once\n        file_tool._run(action='mkdir', path=p.rsplit('/', 1)[0] or '/')\n        result = file_tool._run(action='append', path=p, content=c)\n    else:\n        raise","preventionTips":["Ensure the parent directory exists (mkdir) before the first append to a new path.","Seed new files with action='write' when in doubt, then append.","Always surface the output= portion of the RuntimeError — it holds the sandbox stderr."],"tags":["daytona","append","sandbox","runtimeerror","exit-code"],"backgroundTag":null,"analyzedSha":"754d7323beb2fd042e33444a115ea2d5a47193f0","analyzedAt":"2026-08-15T04:06:56.746Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}