Errors — osc-placement — branch stable/2026.2
Branch
stable/2026.2@402610a21872— repository https://opendev.org/openstack/osc-placement — analysed on 2026-10-28
osc-placement defines no exception class. The inventory found none, and the code uses those of osc-lib and keystoneauth. The user sees a message on stderr and a non-zero exit code. There are three sources of errors.
1. Placement HTTP errors (4xx) → osc-lib exceptions
_wrap_http_exceptions (osc_placement/http.py:33-46) catches keystoneauth's HttpError:
- 4xx: reads **
errors[0].detail** from the JSON body, keeps its last line (Placement puts the explanation after a generic header line), and raises the osc-lib class that matches the status: | Status | osc-lib class | |---|---| | 400 |BadRequest| | 401 |Unauthorized| | 403 |Forbidden| | 404 |NotFound| | 409 |Conflict| | 413 |OverLimit| | other 4xx |CommandError| Mapping built atosc_placement/http.py:23-26; classes from osc-lib 4.7.0. - 5xx and network errors: re-raised as they are (keystoneauth exception).
Hard dependency on the body format: if a 4xx response is not JSON, or has no errors[0].detail, the client raises **KeyError/JSONDecodeError** instead of a readable message [inferred from osc_placement/http.py:40]. A Placement rewrite must keep this body for every 4xx, including the 404 and 405 of routing.
Messages seen in the tests (_rewrite/observed-errors_stable-2026.2.md, 29 combinations) include, for example:
No resource provider with uuid <uuid> found(404);Unable to delete parent resource provider <uuid>: It has child resource providers.(409);Resource provider's generation already changed. Please update the generation and try again.(409 onaggregate setwith a stale--generation);JSON does not validate: 'CUSTOM_lower' does not match '^CUSTOM_[A-Z0-9_]+$'(400).
Only the last line of detail is shown: for JSON validation errors, that is the end of the jsonschema dump.
2. Errors raised before any HTTP call
| Situation | Exception and message | Source |
|---|---|---|
| microversion too low for the command or an option | ValueError "Operation or argument is not supported with version X; requires at least version Y" | osc_placement/version.py:119-147 |
malformed --allocation | ValueError "Incorrect allocation string format", "Resource provider parameter is required for allocation string" | osc_placement/resources/allocation.py:23-31 |
two --allocation with different values for the same provider and class | CommandError "Conflict detected for resource provider … resource class …" | osc_placement/resources/allocation.py:36-42 |
allocation set without any resource | CommandError "At least one resource allocation must be specified" | osc_placement/resources/allocation.py:126-129 |
malformed --resource (inventory) | ValueError "Resource argument must have \"name=value\" format", "… only one colon", "Unknown inventory field %s" | osc_placement/resources/inventory.py:80-99 |
inventory set --aggregate on an empty aggregate | CommandError "No resource providers found in aggregate with uuid %s." | osc_placement/resources/inventory.py:175-178 |
inventory set --aggregate, partial failure | LOG.error per provider, then CommandError "Failed to set inventory for %(ret)s of %(total)s resource providers." | osc_placement/resources/inventory.py:209-224 |
| options without effect for the version | WARNING "--project-id and --user-id options do not affect allocation …", "--consumer-type option does not affect …" | osc_placement/resources/allocation.py:148-157 |
The 93 invocations that fail in the tests (out of 928) are almost all of this kind, or expected 400, 404 and 409 errors (_rewrite/client-contract_stable-2026.2.md, "failed" column).
3. Version negotiation errors
With --os-placement-api-version 1 (the default), a 406 on GET / must carry errors[0].max_version, or the client raises KeyError (osc_placement/http.py:80-86). Any other status than 406 is accepted without checking: the client keeps 1.29.
Source: reverse-spec-osc-placement/02-errors_stable-2026.2.md. The _rewrite/ and _inventory/ files are not published on the site.