Skip to content

bedrockruntime: documentMarshaler.UnmarshalSmithyDocument has incorrect variable references #3288

@adriangomez24

Description

@adriangomez24

Acknowledgements

Describe the bug

The UnmarshalSmithyDocument method in service/bedrockruntime/internal/document/document.go has two bugs on lines 38 and 41:

  1. Line 38: jDecoder.Decode(&v) should be jDecoder.Decode(&jv) - it decodes into the wrong variable
  2. Line 41: NewDocumentUnmarshaler(v).UnmarshalSmithyDocument(&jv) has reversed arguments - should be NewDocumentUnmarshaler(jv).UnmarshalSmithyDocument(v)
  3. Note the declared variable jv is meant to hold the decoded JSON intermediate representation but it is never written to, making it always nil. This causes the subsequent DecodeJSONInterface call to receive nil as input.

Bug location: https://github.com/aws/aws-sdk-go-v2/blob/main/service/bedrockruntime/internal/document/document.go#L28-L41

This was discovered when trying to extract ToolUse.Input from Bedrock Converse API responses.

Regression Issue

  • Select this option if this issue appears to be a regression.

Expected Behavior

UnmarshalSmithyDocument should extract the document contents into the provided destination variable, allowing users to retrieve tool input from Bedrock Converse API responses.

Current Behavior

Returns error: unsupported json type, *interface {}

When using the Converse API with tool use, the ToolUse.Input field contains a documentMarshaler type. Calling UnmarshalSmithyDocument on it fails because the method decodes into &v (a pointer-to-pointer) instead of &jv, then passes the wrong arguments to the final unmarshal call.

Reproduction Steps

package main

import (
	"bytes"
	"encoding/json"
	"fmt"

	smithydocumentjson "github.com/aws/smithy-go/document/json"
)

// Copied from bedrockruntime/internal/document/document.go
type documentMarshaler struct {
	value interface{}
}

func (m *documentMarshaler) MarshalSmithyDocument() ([]byte, error) {
	return smithydocumentjson.NewEncoder().Encode(m.value)
}

func (m *documentMarshaler) UnmarshalSmithyDocument(v interface{}) error {
	mBytes, err := m.MarshalSmithyDocument()
	if err != nil {
		return err
	}
	jDecoder := json.NewDecoder(bytes.NewReader(mBytes))
	jDecoder.UseNumber()
	var jv interface{}
	if err := jDecoder.Decode(&v); err != nil { // BUG: should be &jv
		return err
	}
	return NewDocumentUnmarshaler(v).UnmarshalSmithyDocument(&jv) // BUG: reversed
}

type documentUnmarshaler struct {
	value interface{}
}

func (m *documentUnmarshaler) UnmarshalSmithyDocument(v interface{}) error {
	return smithydocumentjson.NewDecoder().DecodeJSONInterface(m.value, v)
}

func NewDocumentUnmarshaler(v interface{}) *documentUnmarshaler {
	return &documentUnmarshaler{value: v}
}

func main() {
	// Simulates what Bedrock returns for tool input
	doc := &documentMarshaler{value: map[string]interface{}{"query": "bitcoin price"}}

	var result interface{}
	err := doc.UnmarshalSmithyDocument(&result)

	if err != nil {
		fmt.Printf("ERROR: %v\n", err) // Prints: unsupported json type, *interface {}
	} else {
		fmt.Printf("Result: %+v\n", result)
	}

	// Workaround: MarshalSmithyDocument works correctly
	jsonBytes, _ := doc.MarshalSmithyDocument()
	fmt.Printf("Workaround: %s\n", string(jsonBytes)) // Prints: {"query":"bitcoin price"}
}

Possible Solution

I'm aware that this file was created using smithy-go-codegen.

func (m *documentMarshaler) UnmarshalSmithyDocument(v interface{}) error {
	mBytes, err := m.MarshalSmithyDocument()
	if err != nil {
		return err
	}

	jDecoder := json.NewDecoder(bytes.NewReader(mBytes))
	jDecoder.UseNumber()

	var jv interface{}
	if err := jDecoder.Decode(&jv); err != nil {
		return err
	}

	return NewDocumentUnmarshaler(jv).UnmarshalSmithyDocument(v)
}

Additional Information/Context

No response

AWS Go SDK V2 Module Versions Used

github.com/aws/aws-sdk-go-v2 v1.36.3
github.com/aws/aws-sdk-go-v2/service/bedrockruntime v1.47.2
github.com/aws/smithy-go v1.22.3

Compiler and Version used

go version go1.25.1 darwin/arm64

Operating System and version

macOS Tahoe 26.2

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugThis issue is a bug.response-requestedWaiting on additional info and feedback. Will move to "closing-soon" in 7 days.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions