{"record":{"id":"2c1cf8489471b2c7","repo":"agentscope-ai/agentscope","slug":"cannot-append-datablock-with-url-source-or-differe","errorCode":null,"errorMessage":"Cannot append DataBlock with URL source or different source types: {target_block.source} vs {chunk_block.source}","messagePattern":"Cannot append DataBlock with URL source or different source types: (.+?) vs (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/agentscope/tool/_response.py","lineNumber":114,"sourceCode":"                    if isinstance(\n                        target_block.source,\n                        Base64Source,\n                    ) and isinstance(chunk_block.source, Base64Source):\n                        # Accumulate independently encoded base64 chunks.\n                        target_block.source.data = _merge_base64_chunks(\n                            target_block.source.data,\n                            chunk_block.source.data,\n                        )\n                        # Update the newest media type and name if provided\n                        target_block.name = (\n                            chunk_block.name or target_block.name\n                        )\n                        target_block.source.media_type = (\n                            chunk_block.source.media_type\n                            or target_block.source.media_type\n                        )\n                    else:\n                        raise ValueError(\n                            \"Cannot append DataBlock with URL source or \"\n                            f\"different source types: {target_block.source} \"\n                            f\"vs {chunk_block.source}\",\n                        )\n                else:\n                    # For different block types with the same ID, we just\n                    # append the new block with a new ID to avoid the conflict\n                    new_chunk_block = chunk_block.model_copy(deep=True)\n                    new_chunk_block.id = _generate_id()\n                    self.content.append(new_chunk_block)\n\n            else:\n                # Append a copy to avoid modifying the original chunk\n                self.content.append(chunk_block.model_copy(deep=True))\n\n                # Update the index mapping for the new block\n                current_ids_to_index[chunk_block.id] = len(self.content) - 1\n","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/agentscope-ai/agentscope/blob/e90f1c7592896cc95f6e5ee506194f533378247d/src/agentscope/tool/_response.py#L96-L132","documentation":"ToolResponse.append_chunk refuses to merge DataBlocks when the existing target block and the incoming chunk block have incompatible sources (URL vs base64) or different source types; only same-type base64 merges are supported.","triggerScenarios":"Streaming a tool response where the same block id first carries a URL source then a base64 chunk (or vice versa), causing append_chunk to hit the mismatch branch. Reached via call_tool chunk aggregation.","commonSituations":"MCP servers switching transfer modes mid-stream, or a server that sends the first chunk as a URL reference and later chunks as inline base64 with the same block id.","solutions":["Fix the server to use a consistent source type for a given block id","Start a new block (different id) when switching from URL to inline data","Catch ValueError in append_chunk and keep blocks separate instead of merging"],"exampleFix":"# before\nresp.append_chunk(chunk)  # url block + base64 chunk, same id\n# after\nif target_block.source.type != chunk_block.source.type:\n    chunk_block.id = new_id  # keep as separate block\nresp.append_chunk(chunk)","handlingStrategy":"type-guard","validationCode":"same_type = target.source.type == chunk.source.type and target.source.type == 'base64'","typeGuard":"def can_append(target_block, chunk_block) -> bool:\n    return target_block.source.type == chunk_block.source.type == 'base64'","tryCatchPattern":"try:\n    resp.append_chunk(chunk)\nexcept ValueError as e:\n    if 'different source types' in str(e):\n        chunk.id = fresh_id\n    raise","preventionTips":["Use one transfer mode (URL or base64) per block id","Re-id blocks when switching source types","Test streaming tool responses against the aggregator"],"tags":["mcp","streaming","response-merge","data-block"],"backgroundTag":"incompatible-response-chunks","analyzedSha":"e90f1c7592896cc95f6e5ee506194f533378247d","analyzedAt":"2026-08-28T18:24:12.087Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}