{"record":{"id":"2c64278b01d11f73","repo":"pulumi/pulumi","slug":"expected-opts2-to-be-a-invokeoptions-instance","errorCode":null,"errorMessage":"Expected opts2 to be a InvokeOptions instance","messagePattern":"Expected opts2 to be a InvokeOptions instance","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"sdk/python/lib/pulumi/invoke.py","lineNumber":114,"sourceCode":"           from `opts1`.\n\n        3. For the purposes of merging `depends_on` is always treated\n           as collections, even if only a single value was provided.\n\n        4. Attributes with value 'None' will not be copied over.\n\n        This method can be called either as static-method like `InvokeOptions.merge(opts1, opts2)`\n        or as an instance-method like `opts1.merge(opts2)`.  The former is useful for cases where\n        `opts1` may be `None` so the caller does not need to check for this case.\n        \"\"\"\n        opts1 = InvokeOptions() if opts1 is None else opts1\n        opts2 = InvokeOptions() if opts2 is None else opts2\n\n        if not isinstance(opts1, InvokeOptions):\n            raise TypeError(\"Expected opts1 to be a InvokeOptions instance\")\n\n        if not isinstance(opts2, InvokeOptions):\n            raise TypeError(\"Expected opts2 to be a InvokeOptions instance\")\n\n        dest = copy.copy(opts1)\n        source = opts2\n\n        dest.parent = dest.parent if source.parent is None else source.parent\n        dest.provider = dest.provider if source.provider is None else source.provider\n        dest.plugin_download_url = (\n            dest.plugin_download_url\n            if source.plugin_download_url is None\n            else source.plugin_download_url\n        )\n        dest.version = dest.version if source.version is None else source.version\n\n        return dest\n\n\nclass InvokeOutputOptions(InvokeOptions):\n    \"\"\"","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/pulumi/pulumi/blob/793f7b2e160db4321fb7fb6b0607461e01cb251e/sdk/python/lib/pulumi/invoke.py#L96-L132","documentation":"Same validation as opts1, applied to the second InvokeOptions argument of the merge helper. The second options object supplies overrides (parent, provider, version); if it is not an InvokeOptions instance a TypeError is raised.","triggerScenarios":"Passing a ResourceOptions, InvokeOutputOptions, dict, or string as opts2 to the invoke options merge helper.","commonSituations":"Swapping argument order or passing resource-style options in invoke helpers; refactors where a function parameter changed type; tests passing mocks that aren't InvokeOptions.","solutions":["Wrap the value in InvokeOptions(...) before merging","Convert ResourceOptions fields into InvokeOptions equivalents","Fix argument order if an options object landed in the wrong position","Update test doubles to be real InvokeOptions instances"],"exampleFix":"// before\nmerged = merge_invoke_opts(opts1, {'parent': p})\n// after\nmerged = merge_invoke_opts(opts1, pulumi.InvokeOptions(parent=p))","handlingStrategy":"type-guard","validationCode":"if opts2 is not None and not isinstance(opts2, pulumi.InvokeOptions):\n    raise TypeError('opts2 must be InvokeOptions')","typeGuard":"def is_invoke_options2(o) -> bool:\n    return o is None or isinstance(o, pulumi.InvokeOptions)","tryCatchPattern":"try:\n    merged = merge_invoke_opts(opts1, opts2)\nexcept TypeError as e:\n    if 'opts2' in str(e):\n        opts2 = pulumi.InvokeOptions()\n        merged = merge_invoke_opts(opts1, opts2)","preventionTips":["Check argument order when passing options to merge helpers","Convert dicts/options objects to InvokeOptions explicitly","Annotate parameters as Optional[InvokeOptions]","Add unit tests for option merging edge cases"],"tags":["python","invoke","type-error"],"backgroundTag":"wrong-options-type","analyzedSha":"793f7b2e160db4321fb7fb6b0607461e01cb251e","analyzedAt":"2026-08-31T09:36:43.099Z","schemaVersion":2},"datasetVersion":"2026-09-01T08:17:40.651Z"}