Skip to content

aws configure set: UnboundLocalError (crash) when updating an empty nested config section #10587

Description

@Adityaj0

Describe the bug

ConfigFileWriter._update_subattributes (awscli/customizations/configure/writer.py) is responsible for writing values into a nested config section, e.g.:

[default]
s3 =
    signature_version = s3v4
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())
            key_name = match.group(1).strip()
            if key_name in values:
                ...
        if starting_indent == current_indent or \
                self.SECTION_REGEX.search(line) is not None:
            ...

current_indent is only assigned inside if match is not None:. If the nested section is currently empty (e.g. s3 = with no sub-keys yet under it — a completely valid, documented config state, e.g. right after s3 = is first created, or hand-edited), then on the very first loop iteration:

  • If the next line is another [section] header (no OPTION_REGEX match), current_indent was never assigned, and the reference at if starting_indent == current_indent raises UnboundLocalError.
  • If the empty s3 = stanza is the last line in the file, the for loop range is empty, so current_indent (and i) are never assigned, and the else clause of the for/else raises the same error.

Repro

import tempfile, os
from awscli.customizations.configure.writer import ConfigFileWriter

content = "[default]\ns3 =\n[profile foo]\nfoo = bar\n"
fd, path = tempfile.mkstemp()
open(path, 'w').write(content)

w = ConfigFileWriter()
w.update_config({'__section__': 'default', 's3': {'addressing_style': 'path'}}, path)

Output:

Traceback (most recent call last):
  ...
  File "awscli/customizations/configure/writer.py", line 231, in _update_subattributes
    if starting_indent == current_indent or \
                          ^^^^^^^^^^^^^^
UnboundLocalError: cannot access local variable 'current_indent' where it is not associated with a value

Same crash (different line) when s3 = is the last line of the file with nothing after it.

Real-world trigger

Running aws configure set s3.<key> <value> (or s3api.<key>, or any nested <section>.<key> set) against a config file where the target nested section exists but has no sub-keys under it yet throws an unhandled UnboundLocalError instead of writing the value.

Suggested fix

Initialize current_indent = None (and i = index - 1) before the loop, so a line/range with no OPTION_REGEX match doesn't leave the variables unbound, while preserving the existing control flow (None never equals starting_indent, so behavior for all previously-passing cases is unchanged).

I have a PR ready with this fix plus two new regression tests covering both empty-stanza cases (followed by another section, and at end-of-file). Both new tests reproduce the UnboundLocalError against the current code and pass with the fix; full tests/unit/customizations/configure/ (109) and tests/functional/configure/ (33) suites pass with no regressions.

Environment

  • aws-cli develop branch (current)

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