{"record":{"id":"627a474dca472ce1","repo":"owasp-amass/amass","slug":"createassetsbulk-asset-type-required","errorCode":null,"errorMessage":"CreateAssetsBulk: asset type required","messagePattern":"CreateAssetsBulk: asset type required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/api/client/v1/client.go","lineNumber":255,"sourceCode":"\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"createAsset: status=%s\", resp.Status)\n\t\t}\n\t\treturn \"\", fmt.Errorf(\"createAsset: status=%s error=%s\", resp.Status, msg)\n\t}\n\n\tvar r AddAssetResponse\n\tif err := json.Unmarshal([]byte(resp.Body), &r); err != nil {\n\t\treturn \"\", err\n\t}\n\treturn r.EntityID, nil\n}\n\n// Creates multiple assets in bulk on the server associated with the provided token.\nfunc (c *Client) CreateAssetsBulk(ctx context.Context, token uuid.UUID, atype string, assets []oam.Asset) (int, error) {\n\tatype = strings.ToLower(strings.TrimSpace(atype))\n\n\tif atype == \"\" {\n\t\treturn 0, fmt.Errorf(\"CreateAssetsBulk: asset type required\")\n\t}\n\tif len(assets) > MaxBulkItems {\n\t\treturn 0, fmt.Errorf(\"CreateAssetsBulk: too many items; max=%d\", MaxBulkItems)\n\t}\n\n\titems := make([]json.RawMessage, 0, len(assets))\n\tfor _, asset := range assets {\n\t\tif !strings.EqualFold(atype, string(asset.AssetType())) {\n\t\t\treturn 0, fmt.Errorf(\"CreateAssetsBulk: mixed asset types not allowed\")\n\t\t}\n\n\t\traw, err := asset.JSON()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\titems = append(items, json.RawMessage(raw))\n\t}\n","sourceCodeStart":237,"sourceCodeEnd":273,"githubUrl":"https://github.com/owasp-amass/amass/blob/79299dce87b0085db0f2f4ef3e9c52cccb49f514/engine/api/client/v1/client.go#L237-L273","documentation":"CreateAssetsBulk validates its atype parameter client-side before building the bulk request. An empty (or whitespace-only) asset type string cannot form the bulk endpoint path {base}/sessions/{token}/assets/{atype}:bulk, so the client fails fast with this error without any network call.","triggerScenarios":"Calling Client.CreateAssetsBulk(ctx, token, \"\", assets) or with atype containing only spaces/tabs (trimmed to empty).","commonSituations":"atype read from config/environment that was never set, a variable that is an empty string due to failed string parsing, or passing a nil-valued string from another layer.","solutions":["Pass a non-empty asset type string, e.g. string(oam.Domain) or \"domain\".","Trim/validate atype at the call site before invoking CreateAssetsBulk.","Fix the config/env source that yielded the empty value.","Ensure case is consistent (client lowercases internally, but value must be non-empty)."],"exampleFix":"// before\nclient.CreateAssetsBulk(ctx, token, cfgAssetType, assets)\n// after\nif strings.TrimSpace(cfgAssetType) == \"\" { return errors.New(\"asset type not configured\") }\ncount, err := client.CreateAssetsBulk(ctx, token, cfgAssetType, assets)","handlingStrategy":"validation","validationCode":"atype = strings.ToLower(strings.TrimSpace(atype))\nif atype == \"\" { return errors.New(\"CreateAssetsBulk: asset type required\") }","typeGuard":"func validBulkAtype(atype string) bool { return strings.TrimSpace(atype) != \"\" }","tryCatchPattern":"if err := validateAtype(atype); err != nil { return err } // pre-check\ncount, err := client.CreateAssetsBulk(ctx, token, atype, assets)\nif err != nil { return fmt.Errorf(\"bulk add failed: %w\", err) }","preventionTips":["Pass oam.AssetType constants rather than ad-hoc strings.","Validate configuration values that feed atype at startup.","Trim and lowercase asset type strings before use.","Fail fast on empty config instead of letting the client reject the call."],"tags":["validation","api-client","bulk-assets"],"backgroundTag":"missing-required-argument","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"}