owasp-amass/amass · error

createAsset: status=%s error=%s

Error message

createAsset: status=%s error=%s

What it means

CreateAsset's informative variant: the server returned non-200 and its JSON error body parsed successfully, so the client surfaces the server's own error message alongside the HTTP status. The asset was not created.

Source

Thrown at engine/api/client/v1/client.go:240

	sessionID := token.String()
	u := fmt.Sprintf("%s/sessions/%s/assets/%s", c.base, sessionID, atype)
	resp, err := amasshttp.RequestWebPage(ctx, c.httpClient, &amasshttp.Request{
		URL:    u,
		Body:   string(raw),
		Method: http.MethodPost,
		Header: amasshttp.Header{"Content-Type": []string{"application/json"}},
	})
	if err != nil {
		return "", err
	}

	if resp.StatusCode != http.StatusOK {
		msg, err := readJSONError(resp.Body)
		if err != nil {
			return "", fmt.Errorf("createAsset: status=%s", resp.Status)
		}
		return "", fmt.Errorf("createAsset: status=%s error=%s", resp.Status, msg)
	}

	var r AddAssetResponse
	if err := json.Unmarshal([]byte(resp.Body), &r); err != nil {
		return "", err
	}
	return r.EntityID, nil
}

// Creates multiple assets in bulk on the server associated with the provided token.
func (c *Client) CreateAssetsBulk(ctx context.Context, token uuid.UUID, atype string, assets []oam.Asset) (int, error) {
	atype = strings.ToLower(strings.TrimSpace(atype))

	if atype == "" {
		return 0, fmt.Errorf("CreateAssetsBulk: asset type required")
	}
	if len(assets) > MaxBulkItems {
		return 0, fmt.Errorf("CreateAssetsBulk: too many items; max=%d", MaxBulkItems)

View on GitHub (pinned to 79299dce87)

Solutions

  1. Read the error=%s message: it is the server's explanation of the rejection.
  2. Ensure asset.AssetType() matches the endpoint type segment derived from it (client derives it automatically — verify the concrete asset type is supported).
  3. Re-validate required asset fields before sending.
  4. Re-authenticate if the server reported an auth failure.
  5. Retry on transient 5xx statuses.

Example fix

// before
_, err := client.CreateAsset(ctx, token, asset)
// after
_, err := client.CreateAsset(ctx, token, asset)
if err != nil && strings.Contains(err.Error(), "status=409") {
    // asset already exists; treat as success or deduplicate first
}
Defensive patterns

Strategy: try-catch

Validate before calling

if token == uuid.Nil { return errors.New("session token not initialized") }
if _, err := asset.JSON(); err != nil { return err }

Type guard

func isServerError(err error) bool { return err != nil && strings.Contains(err.Error(), "status=5") }

Try / catch

id, err := client.CreateAsset(ctx, token, asset)
if err != nil {
    switch {
    case strings.Contains(err.Error(), "status=401"): token = reauth(ctx)
    case strings.Contains(err.Error(), "status=409"): /* dedupe */
    default: return err
    }
}

Prevention

When it happens

Trigger: Calling Client.CreateAsset when the server rejects the asset — invalid session token (401), unknown asset type path (404), failed validation/storage (400/500) — with a well-formed JSON error body.

Common situations: Posting an asset whose fields fail server-side validation, using a token after session teardown, or a type mismatch between the asset and the URL segment.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of owasp-amass/amass@79299dce87 (2026-09-06). Data as JSON: /api/errors/ac960cdf2e8e2578. Report an issue: GitHub.