[util-dynamodb]: `marshall` types allow passing `undefined` at compile time, but always throws at runtime

See original GitHub issue

Describe the bug

When using marshall, it’s considered valid at compile time to pass in undefined but this will always throw an error at runtime.

Your environment

Ubuntu 18.04 via WSLv1

SDK version number

@aws-sdk/util-dynamodb@3.8.1

Is the issue in the browser/Node.js/ReactNative?

Node.js

Details of the browser/Node.js/ReactNative version

14.16.0

Steps to reproduce

import { marshall } from '@aws-sdk/util-dynamodb';

marshall(undefined);

Observed behavior

TypeScript does not give any compiler errors. At runtime, code throws the following:

Error: Pass options.removeUndefinedValues=true to remove undefined values from map/array/set.
    at Object.convertToAttr (.../node_modules/@aws-sdk/util-dynamodb/dist/cjs/convertToAttr.js:13:15)
    at Object.marshall (.../node_modules/@aws-sdk/util-dynamodb/dist/cjs/marshall.js:11:53)

This behaviour occurs regardless of if { removeUndefinedValues: true } is passed or not.

Expected behavior

TypeScript gives a compiler error, preventing undefined being passed to marshall.

Additional context

The reason for this is because the marshall function takes a generic which is constrained to being an object whose keys are of itself, which collapses down into {} which in TypeScript is equivalent to any.

This should be fixable by just using K: string instead of K in keyof T (playground link).

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:2
  • Comments:5

github_iconTop GitHub Comments

1reaction
pull-taskcommented, Jun 6, 2022

With the removeUndefinedValues option, it is implied that we can decide whether to process the key-value pairs that have a value of undefined or whether to filter them out. The default is to process them, that is, removeUndefinedValues: false.

As a consequence of this bug, one must set removeUndefinedValues: true to avoid the error.

Although I suspect most code would behave the same whether myKey: undefined was present or absent from the data, not all code will behave the same.

For example: Object.keys({a:1, b: undefined, c:3}) results in [ ‘a’, ‘b’, ‘c’ ], while Object.keys({a:1, c:3}) results in [ ‘a’, ‘c’ ].

1reaction
petermorlioncommented, Jan 4, 2022

@kennu I got the same message and fixed it by adding the option in the constructor of my DynamoDBDocumentClient. Using TypeScript:

const dynamoClient = DynamoDBDocumentClient.from(new DynamoDBClient({
    apiVersion: "2012-08-10",
    region: process.env.AWS_REGION
}), {
    marshallOptions: {
        removeUndefinedValues: true
    }
});
Read more comments on GitHub >

github_iconTop Results From Across the Web

@aws-sdk/util-dynamodb | AWS SDK for JavaScript v3
Convert a DynamoDB AttributeValue object to its equivalent JavaScript type. Parameters. data: AttributeValue. The DynamoDB record to convert to JavaScript type.
Read more >
DynamoDB / marshal function complains about an ...
The marshal(..) function will throw this error if it encounters an attribute that is undefined. marshall({ name: "John", age: undefined, }).
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found