{"record":{"id":"3e85995b115281e4","repo":"pulumi/pulumi","slug":"assetarchive-assets-must-be-a-dictionary","errorCode":null,"errorMessage":"AssetArchive assets must be a dictionary","messagePattern":"AssetArchive assets must be a dictionary","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"sdk/python/lib/pulumi/asset.py","lineNumber":88,"sourceCode":"        self.uri = uri\n\n\nclass Archive:\n    \"\"\"\n    Archive represents a collection of named assets.\n    \"\"\"\n\n\nclass AssetArchive(Archive):\n    \"\"\"\n    An AssetArchive is an archive created from an in-memory collection of named assets or other archives.\n    \"\"\"\n\n    assets: dict[str, Union[Asset, Archive]]\n\n    def __init__(self, assets: dict[str, Union[Asset, Archive]]) -> None:\n        if not isinstance(assets, dict):\n            raise TypeError(\"AssetArchive assets must be a dictionary\")\n        for k, v in assets.items():\n            if not isinstance(k, str):\n                raise TypeError(\"AssetArchive keys must be strings\")\n            if not isinstance(v, Asset) and not isinstance(v, Archive):\n                raise TypeError(\n                    \"AssetArchive assets must contain only Assets or Archives\"\n                )\n        self.assets = assets\n\n\nclass FileArchive(Archive):\n    \"\"\"\n    A FileArchive is a file-based archive, or collection of file-based assets.  This can be\n    a raw directory or a single archive file in one of the supported formats (.tar, .tar.gz, or .zip).\n    \"\"\"\n\n    path: str\n","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/pulumi/pulumi/blob/793f7b2e160db4321fb7fb6b0607461e01cb251e/sdk/python/lib/pulumi/asset.py#L70-L106","documentation":"AssetArchive wraps a dictionary of named Assets/Archives. The constructor checks isinstance(assets, dict) and raises TypeError if the argument is any other type (list, tuple, None, etc.), since later serialization relies on dict semantics.","triggerScenarios":"Calling AssetArchive() with a list, tuple, None, or a non-dict mapping like a plain object.","commonSituations":"Building an archive from a list of files and forgetting to zip them into a dict, or passing None when a variable is unset.","solutions":["Wrap items in a dict: AssetArchive({\"name\": FileAsset(path), ...})","If you have a list of (key, value) pairs, convert with dict(pairs)","Handle None by providing a default empty dict"],"exampleFix":"// before\narchive = AssetArchive([FileAsset(\"index.js\")])\n// after\narchive = AssetArchive({\"index.js\": FileAsset(\"index.js\")})","handlingStrategy":"type-guard","validationCode":"if not isinstance(assets, dict):\n    assets = dict(assets) if isinstance(assets, (list, tuple)) else {}","typeGuard":"def is_asset_archive_input(v: object) -> bool:\n    return isinstance(v, dict)","tryCatchPattern":"try:\n    archive = AssetArchive(items)\nexcept TypeError as e:\n    logging.error(\"AssetArchive input invalid: %s\", e)\n    archive = AssetArchive(dict(items))","preventionTips":["Always build asset archives as dicts of name -> Asset/Archive","Wrap collections of paths with a dict comprehension {name: FileAsset(p)}","Default None inputs to {} before constructing"],"tags":["python","validation","assets"],"backgroundTag":"invalid-argument-type","analyzedSha":"793f7b2e160db4321fb7fb6b0607461e01cb251e","analyzedAt":"2026-08-31T09:36:43.099Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}