Skip to content

Commit 60e195c

Browse files
VirtueMeclaude
andauthored
fix(stateMachine): handle plain string Fn::Sub when useExactVersion is true (#744)
When a state machine uses pseudo-parameters (#{...}) but no lambda function references, Fn::Sub is set to a plain string rather than an array. The useExactVersion code path then tried to assign to index [1] of that string, throwing a TypeError in strict mode. Fix by converting the plain string form to the array form [template, {}] before applying the version conversion. Closes #488 Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 72860ca commit 60e195c

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

lib/deploy/stepFunctions/compileStateMachines.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,9 @@ module.exports = {
167167
}
168168
}
169169
if (stateMachineObj.useExactVersion === true && DefinitionString['Fn::Sub']) {
170+
if (!Array.isArray(DefinitionString['Fn::Sub'])) {
171+
DefinitionString['Fn::Sub'] = [DefinitionString['Fn::Sub'], {}];
172+
}
170173
const params = DefinitionString['Fn::Sub'][1];
171174
const f = convertToFunctionVersion.bind(this);
172175
const converted = _.mapValues(params, f);

lib/deploy/stepFunctions/compileStateMachines.test.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1277,6 +1277,42 @@ describe('#compileStateMachines', () => {
12771277
.to.equal('arn:aws:lambda:us-east-1:1234567890:function:world');
12781278
});
12791279

1280+
it('should not throw when useExactVersion is true and definition uses pseudo-parameters but no lambda refs', () => {
1281+
serverless.service.stepFunctions = {
1282+
stateMachines: {
1283+
myStateMachine1: {
1284+
id: 'Test',
1285+
useExactVersion: true,
1286+
definition: {
1287+
StartAt: 'BatchJob',
1288+
States: {
1289+
BatchJob: {
1290+
Type: 'Task',
1291+
Resource: 'arn:aws:states:::batch:submitJob.sync',
1292+
Parameters: {
1293+
JobName: 'MyJob',
1294+
JobDefinition: '#{SlsJobDefinition}',
1295+
JobQueue: '#{SlsJobQueue}',
1296+
},
1297+
End: true,
1298+
},
1299+
},
1300+
},
1301+
},
1302+
},
1303+
};
1304+
1305+
expect(() => serverlessStepFunctions.compileStateMachines()).to.not.throw();
1306+
1307+
const stateMachine = serverlessStepFunctions.serverless.service
1308+
.provider.compiledCloudFormationTemplate.Resources.Test;
1309+
const { 'Fn::Sub': fnSub } = stateMachine.Properties.DefinitionString;
1310+
1311+
expect(Array.isArray(fnSub)).to.equal(true);
1312+
expect(fnSub[0]).to.include('${SlsJobDefinition}');
1313+
expect(fnSub[0]).to.include('${SlsJobQueue}');
1314+
});
1315+
12801316
it('should do nothing if there are no ref to lambda functions, even if useExactVersion is true', () => {
12811317
serverless.service.stepFunctions = {
12821318
stateMachines: {

0 commit comments

Comments
 (0)