Skip to content
FlutterDocs

[Solved] An InputDecorator, which is typically created by a TextField, cannot have an unbounded width

Verified Solution Tested on Flutter 3.47.7 • Dart 3.13.5
Jump to Updated Flutter Example ↓

In this post we are going to show you the cause and solution of the error “An InputDecorator, which is typically created by a TextField, cannot have an unbounded width” Error which is caused by TextField() or TextFormField() widget.

Error Message:

══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞══════════════════════
The following assertion was thrown during performLayout():
An InputDecorator, which is typically created by a TextField, cannot have an unbounded width.
This happens when the parent widget does not provide a finite width constraint. For example, if the
InputDecorator is contained by a Row, then its width must be constrained. An Expanded widget or a
SizedBox can be used to constrain the width of the InputDecorator or the TextField that contains it.
'package:flutter/src/material/input_decorator.dart':
Failed assertion: line 959 pos 7: 'layoutConstraints.maxWidth < double.infinity'

Either the assertion indicates an error in the framework itself, or we should provide substantially
more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
  https://github.com/flutter/flutter/issues/new?template=2_bug.md

The relevant error-causing widget was:
  TextField TextField:file:///C:/flutter_apps/testapp/lib/main.dart:34:23

Cause of Error:

This error happens when TextField() and TextFormField() widgets are placed inside the Parent widget which has no constrained widget. For example:

Row(
  children: [
    TextField(),
  ],
)

In the case of TextField or TextFormField inside Positioned() widget too, you may get this error:

Positioned(
  bottom:0,
  child: TextField()
) //Error: An InputDecorator, which is typically 
  //created by a TextField, cannot have an unbounded width.

Here, TextField() takes the width of Row() but Row() has infinite width.

Solution of Error:

To solve this error, TextField() or TextFormField() must have parents with finite or bounded width. For example, you can wrap TextField() with Expanded() widget.

Row(
  children: [
    Expanded(
      child:TextField()
    )
  ],
)

Here, Expanded takes the width of maximum to the width of the screen, and TextField() widget inside it will have bounded height.

OR, wrap TextField() width with Flexible() widget.

Row(
  children: [
    Flexible(
      child:TextField()
    )
  ],
)

If you are using TextField or TextFormField() inside Positioned() widget, then place your widget like below:

Positioned(
  bottom:100,
  left: 0,  //0 is starting at left, use it to give left-margin
  right:0,  //0 is ending at right, use it to give right-margin
  child: Container(
    child:TextField()
  )
)

In this way, you can solve the “An InputDecorator, which is typically created by a TextField, cannot have an unbounded width” Error on Flutter. For proper TextField layout and constraints, review TextField hints and styling and configuring minimum and maximum widget dimensions.

Updated Flutter Example
SDK: Flutter 3.47.7 • Dart 3.13.5 Verified on Flutter 3.47.7 (Stable)

Updated Flutter Example

Resolving InputDecorator Unbounded Width in Flex Layouts

Key Implementation Details & Modern Differences:

  • Bounded Constraint Resolution: Wraps TextField with Expanded inside a horizontal Row, satisfying InputDecorator requirements for finite horizontal constraints.
  • Material 3 InputDecoration: Incorporates modern OutlineInputBorder with rounded corners, filled: true, and integrated prefix search icons.
  • Clean State Handling: Demonstrates proper TextEditingController lifecycle management with mandatory disposal.
Updated Flutter Example Code
import 'package:flutter/material.dart';

void main() {
  runApp(const MaterialApp(home: ModernInputDecoratorFixDemo()));
}

class ModernInputDecoratorFixDemo extends StatefulWidget {
  const ModernInputDecoratorFixDemo({super.key});

  @override
  State<ModernInputDecoratorFixDemo> createState() =>
      _ModernInputDecoratorFixDemoState();
}

class _ModernInputDecoratorFixDemoState
    extends State<ModernInputDecoratorFixDemo> {
  final TextEditingController _controller = TextEditingController();
  String _submittedText = '';

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  void _handleSubmit() {
    setState(() {
      _submittedText = _controller.text.trim();
    });
  }

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);

    return Scaffold(
      appBar: AppBar(title: const Text('InputDecorator Unbounded Width Fix')),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            Text(
              'TextField inside Row Layout',
              style: theme.textTheme.titleMedium,
            ),
            const SizedBox(height: 8),
            const Text(
              'Wrapping TextField with Expanded provides bounded horizontal constraints, '
              'preventing the InputDecorator unbounded width assertion.',
              style: TextStyle(color: Colors.grey),
            ),
            const SizedBox(height: 16),
            // SOLUTION: Wrap TextField in Expanded inside the horizontal Row
            Row(
              children: [
                Expanded(
                  child: TextField(
                    controller: _controller,
                    decoration: InputDecoration(
                      labelText: 'Search Query',
                      hintText: 'Enter search keywords...',
                      prefixIcon: const Icon(Icons.search),
                      border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(12),
                      ),
                      filled: true,
                    ),
                    onSubmitted: (_) => _handleSubmit(),
                  ),
                ),
                const SizedBox(width: 8),
                FilledButton.tonal(
                  onPressed: _handleSubmit,
                  child: const Text('Submit'),
                ),
              ],
            ),
            const SizedBox(height: 24),
            if (_submittedText.isNotEmpty)
              Card.outlined(
                child: Padding(
                  padding: const EdgeInsets.all(16.0),
                  child: Text(
                    'Active Query: $_submittedText',
                    style: theme.textTheme.bodyLarge,
                  ),
                ),
              ),
          ],
        ),
      ),
    );
  }
}
Document History & Archival Record

Original reference snapshot archived April 1, 2023. Updated working solution verified on modern Flutter & Dart SDKs.