You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Redshift is a Query-protocol service and substrate answers it with XML that has no response envelope,
no namespace and no request ID, with every list flattened and one record double-wrapped. No AWS SDK
can decode any of it.
The result is marshalled as the document root and the request-ID parameter is _ string —
accepted and discarded. AWS publishes, for every Redshift operation, the three-level form:
Substrate emits <Cluster>…</Cluster> alone. An SDK looks for {Operation}Response and finds
nothing, so every Redshift response fails to decode — the operation might as well not be routed.
This is the same class as #1013's envelope work on other Query services and the same fix shape.
2. Lists flatten to >member
redshift_types.go:94, :99-100 tag slices so they marshal as bare repeated <member> elements.
AWS publishes the wrapped form — <ClusterNodes><member>…</member><member>…</member></ClusterNodes>
— so even inside a correct envelope the members would be in the wrong place.
3. A single cluster is double-wrapped
redshift_types.go:76:
XMLName xml.Name`xml:"member"`
on the Cluster struct forces <member> around it at every site, including DescribeClusters' single-cluster case and CreateCluster's result, where AWS publishes <Cluster>. The tag is there to make the list form work, which is the wrong layer: the element name
belongs to the field that holds the value, not to the type. Moving it is part of this issue rather
than the record-shape issue, because the two are the same edit.
4. Two error codes carry an unpublished Fault suffix
redshift_plugin.go:143, :216, :536 answer ClusterAlreadyExistsFault and ClusterNotFoundFault. Every Redshift page publishes these as ClusterAlreadyExists and ClusterNotFound, both at 400 — the …Fault spelling is the shape name in the AWS service model,
not the wire code, and the two are different strings. A consumer matching on the published code never
matches.
5. An unrouted operation answers a code Redshift does not publish
10 of Redshift's 141 operations are routed; the other 131 answer InvalidAction/400. Redshift's own
Common Errors page publishes the consolidated fifteen-code list, which does not include InvalidAction — it publishes ValidationError/400 and InvalidParameterCombination/400 among
others. Note this is the opposite of SQS (#1064), whose Common Errors page is still the legacy
generation and does publish InvalidAction, which is why sqs_errors.go:31 is correct and this is
not. The refusal must take a code from Redshift's own page.
Why this matters
This is the largest single fidelity defect found across the nine services, because it is total: not
one Redshift operation can be consumed by an SDK. A consumer's boto3.client("redshift") call
against substrate raises a parse error on the first response, so the service reads as broken rather
than as partial — and 10 routed operations' worth of work is unreachable behind it.
It also means every other Redshift finding in this batch is currently unobservable. The 11-of-63 Cluster members, the available-at-birth state, the unread Marker/MaxRecords — a consumer
cannot see any of them, because they never get a decoded response to look at. So this issue gates the
value of the rest, which is the argument for doing it first among the Redshift work.
Acceptance criteria
Every Redshift response is wrapped in {Operation}Response / {Operation}Result / ResponseMetadata.RequestId with the http://redshift.amazonaws.com/doc/2012-12-01/ namespace,
following the in-tree Query-protocol precedent rather than a new mechanism.
The discarded request-ID parameter is used, so ResponseMetadata.RequestId carries the value
the rest of the emulator already generates and logs.
Lists marshal wrapped (<ClusterNodes><member>…), not flattened.
The XMLName tag moves off the Cluster type onto the fields that hold it, so a single cluster
is <Cluster> and a list element is <member>.
ClusterAlreadyExists and ClusterNotFound are spelled as published, without the Fault
suffix, at all three sites.
An unrouted Redshift action answers a code Redshift's own Common Errors page publishes, not InvalidAction. Record which, and record that SQS's retention of InvalidAction is correct for
SQS — the two pages are different generations and the divergence between them is real.
A test asserts the raw XML of at least one success and one refusal against the published
shape, following iam_shape_members_test.go:115's raw-assertion approach. A test that decodes
into substrate's own structs cannot catch a missing envelope, which is why this survived.
docs/services.md's Redshift section states the envelope shape, the namespace, and what an
unrouted action answers.
Provenance
The envelope, namespace and ResponseMetadata shape are from the Response Syntax and Examples
sections of Redshift's own pages — API_CreateCluster, API_DescribeClusters, API_DeleteCluster —
and the wrapped list form is from the same examples. The ClusterAlreadyExists and ClusterNotFound
code spellings and their 400 statuses are from those pages' Errors sections. The consolidated
fifteen-code Common Errors list, and its omission of InvalidAction, are from Redshift's CommonErrors.html; the SQS contrast is the finding recorded in #1064.
In-tree: emulator/redshift_plugin.go:545-557 (the marshal and the discarded request ID), :143, :216, :536 (the codes); emulator/redshift_types.go:76 (the XMLName tag), :94, :99-100
(the flattened lists). Line citations are from the tree at the commit this issue was filed against.
What
Redshift is a Query-protocol service and substrate answers it with XML that has no response envelope,
no namespace and no request ID, with every list flattened and one record double-wrapped. No AWS SDK
can decode any of it.
1. There is no envelope, namespace or request ID
redshift_plugin.go:545-557:The result is marshalled as the document root and the request-ID parameter is
_ string—accepted and discarded. AWS publishes, for every Redshift operation, the three-level form:
Substrate emits
<Cluster>…</Cluster>alone. An SDK looks for{Operation}Responseand findsnothing, so every Redshift response fails to decode — the operation might as well not be routed.
This is the same class as #1013's envelope work on other Query services and the same fix shape.
2. Lists flatten to
>memberredshift_types.go:94,:99-100tag slices so they marshal as bare repeated<member>elements.AWS publishes the wrapped form —
<ClusterNodes><member>…</member><member>…</member></ClusterNodes>— so even inside a correct envelope the members would be in the wrong place.
3. A single cluster is double-wrapped
redshift_types.go:76:on the
Clusterstruct forces<member>around it at every site, includingDescribeClusters' single-cluster case andCreateCluster's result, where AWS publishes<Cluster>. The tag is there to make the list form work, which is the wrong layer: the element namebelongs to the field that holds the value, not to the type. Moving it is part of this issue rather
than the record-shape issue, because the two are the same edit.
4. Two error codes carry an unpublished
Faultsuffixredshift_plugin.go:143,:216,:536answerClusterAlreadyExistsFaultandClusterNotFoundFault. Every Redshift page publishes these asClusterAlreadyExistsandClusterNotFound, both at 400 — the…Faultspelling is the shape name in the AWS service model,not the wire code, and the two are different strings. A consumer matching on the published code never
matches.
5. An unrouted operation answers a code Redshift does not publish
10 of Redshift's 141 operations are routed; the other 131 answer
InvalidAction/400. Redshift's ownCommon Errors page publishes the consolidated fifteen-code list, which does not include
InvalidAction— it publishesValidationError/400 andInvalidParameterCombination/400 amongothers. Note this is the opposite of SQS (#1064), whose Common Errors page is still the legacy
generation and does publish
InvalidAction, which is whysqs_errors.go:31is correct and this isnot. The refusal must take a code from Redshift's own page.
Why this matters
This is the largest single fidelity defect found across the nine services, because it is total: not
one Redshift operation can be consumed by an SDK. A consumer's
boto3.client("redshift")callagainst substrate raises a parse error on the first response, so the service reads as broken rather
than as partial — and 10 routed operations' worth of work is unreachable behind it.
It also means every other Redshift finding in this batch is currently unobservable. The 11-of-63
Clustermembers, theavailable-at-birth state, the unreadMarker/MaxRecords— a consumercannot see any of them, because they never get a decoded response to look at. So this issue gates the
value of the rest, which is the argument for doing it first among the Redshift work.
Acceptance criteria
{Operation}Response/{Operation}Result/ResponseMetadata.RequestIdwith thehttp://redshift.amazonaws.com/doc/2012-12-01/namespace,following the in-tree Query-protocol precedent rather than a new mechanism.
ResponseMetadata.RequestIdcarries the valuethe rest of the emulator already generates and logs.
<ClusterNodes><member>…), not flattened.XMLNametag moves off theClustertype onto the fields that hold it, so a single clusteris
<Cluster>and a list element is<member>.ClusterAlreadyExistsandClusterNotFoundare spelled as published, without theFaultsuffix, at all three sites.
InvalidAction. Record which, and record that SQS's retention ofInvalidActionis correct forSQS — the two pages are different generations and the divergence between them is real.
shape, following
iam_shape_members_test.go:115's raw-assertion approach. A test that decodesinto substrate's own structs cannot catch a missing envelope, which is why this survived.
docs/services.md's Redshift section states the envelope shape, the namespace, and what anunrouted action answers.
Provenance
The envelope, namespace and
ResponseMetadatashape are from the Response Syntax and Examplessections of Redshift's own pages —
API_CreateCluster,API_DescribeClusters,API_DeleteCluster—and the wrapped list form is from the same examples. The
ClusterAlreadyExistsandClusterNotFoundcode spellings and their 400 statuses are from those pages' Errors sections. The consolidated
fifteen-code Common Errors list, and its omission of
InvalidAction, are from Redshift'sCommonErrors.html; the SQS contrast is the finding recorded in #1064.In-tree:
emulator/redshift_plugin.go:545-557(the marshal and the discarded request ID),:143,:216,:536(the codes);emulator/redshift_types.go:76(theXMLNametag),:94,:99-100(the flattened lists). Line citations are from the tree at the commit this issue was filed against.