{"record":{"id":"981d38ed1d071d7c","repo":"owasp-amass/amass","slug":"unknown-asset-type-s","errorCode":null,"errorMessage":"unknown asset type: %s","messagePattern":"unknown asset type: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/api/server/v1/utils.go","lineNumber":220,"sourceCode":"\t\treturn &a, err\n\tcase strings.ToLower(string(oam.ProductRelease)):\n\t\tvar a oamplat.ProductRelease\n\t\terr := json.Unmarshal(raw, &a)\n\t\treturn &a, err\n\tcase strings.ToLower(string(oam.Service)):\n\t\tvar a oamplat.Service\n\t\terr := json.Unmarshal(raw, &a)\n\t\treturn &a, err\n\tcase strings.ToLower(string(oam.TLSCertificate)):\n\t\tvar a oamcert.TLSCertificate\n\t\terr := json.Unmarshal(raw, &a)\n\t\treturn &a, err\n\tcase strings.ToLower(string(oam.URL)):\n\t\tvar a oamurl.URL\n\t\terr := json.Unmarshal(raw, &a)\n\t\treturn &a, err\n\t}\n\treturn nil, fmt.Errorf(\"unknown asset type: %s\", atype)\n}\n\nfunc defaultContentFilter(asset oam.Asset) (dbt.ContentFilters, error) {\n\tswitch asset.AssetType() {\n\tcase oam.Account:\n\t\treturn dbt.ContentFilters{\"unique_id\": asset.Key()}, nil\n\tcase oam.AutnumRecord:\n\t\treturn dbt.ContentFilters{\"handle\": asset.Key()}, nil\n\tcase oam.AutonomousSystem:\n\t\treturn dbt.ContentFilters{\"number\": asset.Key()}, nil\n\tcase oam.ContactRecord:\n\t\treturn dbt.ContentFilters{\"discovered_at\": asset.Key()}, nil\n\tcase oam.DomainRecord:\n\t\treturn dbt.ContentFilters{\"domain\": asset.Key()}, nil\n\tcase oam.File:\n\t\treturn dbt.ContentFilters{\"url\": asset.Key()}, nil\n\tcase oam.FQDN:\n\t\treturn dbt.ContentFilters{\"name\": asset.Key()}, nil","sourceCodeStart":202,"sourceCodeEnd":238,"githubUrl":"https://github.com/owasp-amass/amass/blob/79299dce87b0085db0f2f4ef3e9c52cccb49f514/engine/api/server/v1/utils.go#L202-L238","documentation":"parseAsset on the server decodes a raw JSON asset into the concrete oam.Asset implementation selected by the atype switch (account, domain, url, etc.). If atype matches none of the supported cases, the server returns this error, which surfaces to the AddAssetTypedHandler/AddAssetsBulkHandler callers as a request rejection.","triggerScenarios":"POSTing an asset to /assets/{atype} (or the bulk endpoint) with an atype string that is not one of the supported oam asset types, misspelled, or in unexpected casing that still fails the lowercase comparison.","commonSituations":"Client and server version skew (new asset type added in client but not in server), typos in atype like \"ipaddress\" vs the supported constant, or hand-crafted API requests.","solutions":["Use an oam.AssetType constant (e.g. oam.Domain, oam.IPAddress) instead of a hand-typed string.","Check server version supports the asset type; upgrade the engine if the type is newer.","Verify spelling/casing against the switch cases in engine/api/server/v1/utils.go parseAsset.","On the client, ensure asset.AssetType() returns a registered type rather than an empty/custom value."],"exampleFix":"// before\nclient.CreateAsset(ctx, token, myCustomAsset{atype: \"hostname\"}) // server: unknown asset type: hostname\n// after\n// use a supported type\na := oamdomain.Domain{Name: \"example.com\"}\nclient.CreateAsset(ctx, token, &a)","handlingStrategy":"validation","validationCode":"supported := map[string]bool{\"account\":true,\"autnumrecord\":true /* ...all switch cases in parseAsset */}\nif !supported[strings.ToLower(atype)] { return fmt.Errorf(\"unsupported asset type %q\", atype) }","typeGuard":"func isKnownAssetType(atype oam.AssetType) bool {\n    switch atype { case oam.Account, oam.Domain, oam.IPAddress, oam.URL /* etc */: return true }\n    return false\n}","tryCatchPattern":"if !isKnownAssetType(asset.AssetType()) { return fmt.Errorf(\"skip unsupported asset type %s\", asset.AssetType()) }\n_, err := client.CreateAsset(ctx, token, asset)\nif err != nil && strings.Contains(err.Error(), \"unknown asset type\") { log skipping; return nil }","preventionTips":["Only construct assets via the supported oam concrete types.","Keep client and engine server versions in sync so new types exist on both sides.","Check parseAsset's switch in engine/api/server/v1/utils.go before introducing new type strings.","Log-and-skip unknown types in collection pipelines instead of failing whole batches."],"tags":["asset-types","validation","api-server"],"backgroundTag":"invalid-enum-value","analyzedSha":"79299dce87b0085db0f2f4ef3e9c52cccb49f514","analyzedAt":"2026-09-06T08:22:48.198Z","contentChangedAt":"2026-09-06T08:22:48.198Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}