Skip to content

aws configure set: UnboundLocalError when nested key is followed by a comment, blank line, or end of file #10554

Description

@Adityaj0

Describe the bug

aws configure set crashes with an internal UnboundLocalError when writing a nested (sub-attribute) value into a config file where the parent key is not immediately followed by another indented option line.

The error surfaces to the user as a bare Python message with no indication of what is wrong with their config:

aws: [ERROR]: cannot access local variable 'current_indent' where it is not associated with a value

The command exits 255 and the config file is left unmodified.

Regression Issue

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

Expected Behavior

aws configure set default.s3.max_concurrent_requests 20 should add the nested value under the existing s3 = key and exit 0.

Current Behavior

The command aborts with UnboundLocalError and exit code 255.

Traceback (with --debug stripped to the relevant frames):

  File "awscli/customizations/configure/writer.py", line 113, in update_config
    self._update_section_contents(contents, section_name, new_values)
  File "awscli/customizations/configure/writer.py", line 210, in _update_section_contents
    j = self._update_subattributes(
  File "awscli/customizations/configure/writer.py", line 246, in _update_subattributes
    starting_indent == current_indent
UnboundLocalError: cannot access local variable 'current_indent' where it is not associated with a value

Reproduction Steps

Any of the following three config files reproduce it. All are valid and all parse correctly with botocore.

1. Parent key followed by a comment

[default]
region = us-east-1
s3 =
# tune these later

2. Parent key is the last line in the file

[default]
s3 =

3. Parent key followed by a blank line

[default]
s3 =

Then run:

$ AWS_CONFIG_FILE=./config aws configure set default.s3.max_concurrent_requests 20

aws: [ERROR]: cannot access local variable 'current_indent' where it is not associated with a value
$ echo $?
255

Possible Solution

In ConfigFileWriter._update_subattributes, current_indent is only assigned inside the if match is not None: branch, but it is read unconditionally a few lines later:

def _update_subattributes(self, index, contents, values, starting_indent):
    index += 1
    for i in range(index, len(contents)):
        line = contents[i]
        match = self.OPTION_REGEX.search(line)
        if match is not None:
            current_indent = len(match.group(1)) - len(match.group(1).lstrip())
            ...
        if (
            starting_indent == current_indent      # <-- may be unbound
            or self.SECTION_REGEX.search(line) is not None
        ):
            ...
    else:
        if starting_indent != current_indent:      # <-- may be unbound
            self._insert_new_values(i, contents, values, '    ')
    return i

Comment and blank lines do not match OPTION_REGEX, so if the first line after the parent key is one of those, current_indent is never bound. If the parent key is the last line of the file the range() is empty, so both current_indent and i are unbound when the else: clause runs.

Seeding current_indent = None and i = index - 1 before the loop fixes all three cases and preserves existing behaviour: None never compares equal to starting_indent, which is exactly the "this line does not end the nested block" behaviour that a stale indent value produced for comments appearing later in a block.

I have a PR ready with a fix and regression tests for all three cases.

CLI version used

aws-cli/2.36.23 (reproduced on v2 at 4c331fc)

Environment details (OS name and version, etc.)

macOS 15 (Darwin 25.2.0), Python 3.12

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-triageThis issue or PR still needs to be triaged.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions